John M. Dlugosz wrote:
A method can refer to private attributes etc. in other objects than
self. This is unlike Smalltalk and like C++. Which objects? Obviously,
those that _have_ them in the first place.

Correct, though those classes also has to trust the calling class:

class MyClass { has $!attr; trusts YourClass }
class YourClass {
    method foo (MyClass $obj) {
        $obj!MyClass::attr; # Access to $obj's private attr
    }
}

Does the variable used as the invocant, or return value if it is an expression,
> have to be statically typed as being of the identical class?

The $obj above must be evaluated to an object of class MyClass.

AFAICS, the spec doesn't really say if a derived class needs to explicitly trust YourClass for it to be used this way:

class MyDerivedClass is MyClass {};
YourClass.foo(MyDerivedClass.new(attr => 1)); # Not sure if this works.

If class C { has $.a; ... }, then I understand that members may refer to
$.a directly but outside of the scope of members defined in the class
they can only be reached by accessors, a() as a method call.

Well, $.a is exactly the same as $(self.a) -- see S12/"are just shorthands of C<self.foo>" for the definition.

Methods in class C may call $!a, which is the private accessor method.
Outside the scope, private methods of class C are invisible.

But, it is also stated that in derived and trusted classes, and even in
the class itself, $.a is an accessor call?

Well, $.a is merely shorthand for $(self.a) so derived classes can call it just fine. However in trusted classes, $.a wouldn't make much sense,
as you need to use either $obj.a or $obj!YourClass::a there.

Is this accessor different from the
function form used outside the class? Why keep the variable syntax?

Because it's jolly convenient, especially in interpolated strings, I suppose:

say "My position is $.x - $.y - $.z";

I'm getting a picture of 3 forms of access: Really direct, direct but
asking the class to access it rather than knowing how storage works, and
indirect that may involve your own code to do other things besides just
get/set the attribute. But I think the middle one can be handled
invisibly by the compiler -- it's no different from a tied hash.

The middle one is not that different from the first one, because from an implementation viewpoint, once YourClass trusts MyClass, then code in MyClass might as well have knowledge about how the storage works.

How private is private? I wonder if what you've called private things
are really more like "protected" in C++ (accessible by the derived
class) and that 'my' attributes are really private, as are submethods.
It's all confused. Who is allowed to access what?

No, private methods are not accessible from derived classes, unless the base class explicitly trusts them -- See L12/"the exclamation form may be used only in the actual class, not in derived classes".

Cheers,
Audrey

Reply via email to