Search code examples
classattributesraku

How can a attribute (which is a class) access the class to which it is an attribute?


A confusing title, I know. But the code should be clear:

class A {
    has $.foo = 1;
    # how can I access B::bar from here?
}

class B {
    has $.bar = 2;
    has A $.a;
    submethod TWEAK {
        $!a = A.new;
    }
}

my $b = B.new;
say $b;    # B.new(bar => 2, a => A.new(foo => 1))
say $b.a;  # A.new(foo => 1)
my $test := $b.a;
say $test; # A.new(foo => 1)

Given $test, how can I access B::bar (which is on the same "level" as $test)?


Solution

  • Personally if I had to do this I'd state that A can have an attribute parent that fulfils a Role HasBar like so.

    role HasBar {
        has $.bar = 2;
    }
    
    class A {
       has $.foo = 1;
       has HasBar $.parent;
    }
    
    class B does HasBar {
        has A $.a;
        submethod TWEAK {
            $!a = A.new( parent => self );
        }
    }
    

    Attributes generally don't (and shouldn't) know if they are contained in another object. So if you want to be able to do that you need to tell them the connection exists. I prefer using Roles to do this as then your A class could be an attribute in lots of different things as long as the container has a bar accessible.