On Fri, Nov 04, 2005 at 12:37:04PM +0100, TSa wrote:
: The above also describes my perception of the $. twigil notation which
: are variables bound through the invocant(s). My mental picture beeing
: one where a method is instanciated as a not yet invoked sub after selecting
: the target code body in the dispatch process and binding the twigils of it
: on the invocant(s). This models twigil variables of the $. form as a kind
: of pointer into the object's state. The information how to perform this
: binding travels along the lines of inheritance. For twigiled vars of the
: private data form $: this knowledge is *not* forwarded in the inheritance
: process. The non-twigiled forms of variables are lexically scoped without
: relation to the object state.
: 
: Question: what is the current state of affairs in @Larry about the private
: instance data notation? Is it still with an underscore as the first char in
: the variable's name? Or are we back with $. and $: twigils?

At the moment $: is dead, and we last left it at:

    has $.foo;          # public
    has $foo;           # private
    has $._foo;         # private storage of $.foo

I like the fact that it makes it easier to name the private $foo
attribute than to name $.foo, and I also like the fact that the
privacy is lexically enforced with $foo.  On the other hand, without
the twigil, it become problematic to write a BUILD routine that
automatically sets attributes.  We can't really allow:

    submethod BUILD ($.public, $private) { }

Instead we get a backwards result like

    submethod BUILD ($.public, $privatearg) {
        $private = $privatearg;
    }

where it becomes *harder* to write the private initializer than the
public one.  That I don't like.  And $._foo is just plain ugly.
So I think we haven't finished thinking this one through.  The $:
approach had the advantage of making a positive visual statement
about the privacy.  Arguably though, the interface of

    submethod BUILD ($.public, $:private) { }

is giving away some info about the private name of a variable.  But
that can't really be helped, and we now have the :foo($bar) syntax
to rename parameters.

But $: was dead for several good reasons, and I think it'll stay dead
for at least some of those reasons.  Maybe we can go back to $!foo
for private vars.  That's easier to type (at least on my keyboard)
than $.foo, and has some connotations of NOT public.  And then maybe,
since $.foo is virtual, $!foo could be the devirtualized storage
for $.foo.  And since .foo is not a self call any more, we don't have
the visual confusion of ! or .! where a term is expected.  self!foo()
is a private method call on yourself (but why not just write $!foo),
while $other!foo() is a private method call on some class that trusts
this class.

Another possibility is to take $? away from the compiler.  All the
compiler variables could go under $= instead, since pod is actually
just one particular kind of compiler-time data, and there's really
no particular mnemonic relationship between ? and the compiler.
But $?foo is harder to type than $!foo.  Maybe we hold $?foo in
reserve for some other kind of attribute scope.

Another possibility is that the twigil is never an official part of
the attribute name, so that when you say

    has $.foo;

you're really declaring the private storage variable $foo, and $.foo
is just how you explicitly refer to it virtually.  To explicitly refer
to it non-virtually you use $!foo, but it means the same as $foo.
It's your choice as to whether you want to be explicit about the
privacy, except in

    submethod BUILD ($.public, $!private) { }

where the ! is required to get autoassignment to $private.  Interestingly,
though, you could write that

    submethod BUILD ($!public, $!private) { }

and get the same effect, since $!public is referring to $public, which
is the private storage for $.public, and in the case of an initializer
you want to be setting the private storage anyway.  Arguably it should
earn you a warning to use a virtual $.public within a submethod rather
than the non-virtual $!public.

: On the same line of thought: is the has declarator also supported outside
: of class declarations? As in
: 
:   my $x has $.blahh;
: 
:   $x.blahh = 42;

The thing that bugs me about that is "my $x" is a variable declaration,
but your "has" declaration seems to want to do something to the type
of a non-existent value in $x.  So I'm not really sure what that
desugars to.

Larry

Reply via email to