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; #=> «4284»
.say for $foo.b; #=> «(42 84)»
.say for $foo.c; #=> «4284»
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 |