Why $.?

0 views
Skip to first unread message

Luke Palmer

unread,
May 16, 2005, 6:02:18 AM5/16/05
to perl6-l...@perl.org
I am currently failing to see the need for a distinction between $.
and $: . The only difference is in whether accessors are *generated*;
the attribute access itself is no different. If you want to refactor
and turn your auto-accessor into a custom one, you have to[1] go
replace $. with $: everywhere it is mentioned.

Luke

[1] Well, you don't have to, but you probably would have written it
with a $: if you knew about the accessor all along. Stylistically, I
don't think it's a good distinction to have, because when there are
explicit accessors present, there is no distinction.

Aaron Sherman

unread,
May 16, 2005, 7:21:54 AM5/16/05
to Luke Palmer, Perl6 Language List
On Mon, 2005-05-16 at 04:02 -0600, Luke Palmer wrote:
> I am currently failing to see the need for a distinction between $.
> and $: . The only difference is in whether accessors are *generated*;

Not at all! There are numerous differences as described in A12:

* The attribute gets a "private" trait
* "we basically force people to document the private/public
distinction every place they reference $:x" -A12
* Prevents access to class variables (e.g. using "our") from
outside the class.
* %$obj notation includes private attributes when inside, but not
when outside the class
* Private variables use a different dispatcher.


Aaron Sherman

unread,
May 16, 2005, 11:50:25 AM5/16/05
to Perl6 Language List
On Mon, 2005-05-16 at 07:21, Aaron Sherman wrote:

> * %$obj notation includes private attributes when inside, but not
> when outside the class

This bit was new to me this morning, when I looked it up, and I'd like
to delve into a bit more.

If the idea is to provide a hash-like thing that contains all attributes
as key/value pairs for purposes of cloning, I think it needs to contain
private members. HOWEVER, I don't think the language should put private
members in there by default (even inside the class, just for
consistency).

Instead, the private members should be asked to place themselves into
the resulting hash via a method in the metaclass which inspects the list
of public attributes, and returns them as key/values, and then inspects
the list of private attributes and looks for an "export" trait on them.
If it's found, the value of said trait is used as the key and the
attribute's accessor method is used to gather the current value.

This means that you can hide or expose data however you like. Here's a
pretty vanilla definition:

class Foo { has $.x is export<x> }

And here's an example that exports a private attribute under a new name,
and encrypts its contents:

class Foo {
has $:x is export<_x>;
method :x($?x) {
my $old = $:x;
if defined $x {
$:x = some_decryption($x);
}
return some_encryption($old);
}
}

You also get a default BUILD submethod with the appropriately named
parameter for setting private attributes.

All of this together allows:

multi method clone ($proto: *%_) {
return $proto.bless(0, *%_, *%$proto);
}

from A12 to actually do the right thing regardless of the privacy of
your attributes, or to explicitly do the "wrong thing" if that's what
you want (for example, a database connection object might choose not to
hand around its socket handle, and let cloning operations build a new
connection with the same initialization parameters).

--
Aaron Sherman <a...@ajs.com>
Senior Systems Engineer and Toolsmith
"It's the sound of a satellite saying, 'get me down!'" -Shriekback


Reply all
Reply to author
Forward
0 new messages