What's the difference between $.attribute and self.attribute inside a class in Raku?

64 Views Asked by At

For example, in this class Foo both methods b and c return the same value:

class Foo {
    method a { 42     }
    method b { $.a    }
    method c { self.a }
}

my $foo = Foo.new;
say $foo.a; #=> 42
say $foo.b; #=> 42
say $foo.c; #=> 42

I noticed I can do the same thing for the other sigil and twigil combinations, e.g., @.scores vs self.score, %.matches vs self.matches, etc.

Edit: I flagged this question as duplicate, however as librasteve points out I failed to realize the subtle distinction mentioned in the answers for the other question isn't the focal point, and might be easily missed especially by someone new to Raku.

1

There are 1 best solutions below

0
uzluisf On

As briefly mentioned in this other SO question's answer, $.method is a shorthand for $(self.method) which means the method's return value is itemized or treated in an item or scalar context. Alternatively you can call item explicitly on self.method, i.e.,, self.method.item.

This contextualization taking place would be more evident if method a returned a list instead:

class Foo {
    method a { 42, 84 }
    method b { $.a    }
    method c { self.a }
}

my $foo = Foo.new;
dd $foo.a; #=> «(42, 84)␤»
dd $foo.b; #=> «$(42, 84)␤»
dd $foo.c; #=> «(42, 84)␤»

Methods a and c returns the list as-is and method b has itemized it. Thus, $.a returns an itemized list while self.a returns a list without any context.

Another way to showcase this is to loop over each method's return value and see how it behaves:

.say for $foo.a; #=> «42␤84␤»
.say for $foo.b; #=> «(42 84)␤»
.say for $foo.c; #=> «42␤84␤»

As shown here, b's return value is treated as a single item, unlike the other methods where for iterates over each element of the list. Contextualization also happens for @.method and %.method, as shown here:

class Bar {
    method a { 1..4 }
    method b { @.a }
    method c { %.a }
    method d { self.a }
}

my $bar = Bar.new;
dd $bar.a; #=> «1..4␤»
dd $bar.b; #=> «(1, 2, 3, 4)␤»
dd $bar.c; #=> «{"1" => 2, "3" => 4}␤»
dd $bar.d; #=> «1..4␤»

The following table summarizes the behavior for contextualized method invocations:

Contextualized Method Invocation Shorthand For Explicit Contextualization
$.method $(self.method) self.method.item
@.method @(self.method) self.method.list
%.method %(self.method) self.method.hash