On 6/26/05, Sam Vilain <[EMAIL PROTECTED]> wrote:
> So, we've got this "my $var is Proxy( ... )" construct in A06.
> Say you've got this class:
>
> class MagicVal {
> has Int $.varies is rw;
>
> method varies returns Int is rw {
> return my $var is Proxy ( :for($.varies),
> :FETCH{ $.varies += 2 },
> :STORE{ $.varies = $_ + 1 },
> );
> }
> }
>
> Firstly, would this be correct syntax? In particular, what should
> I call $.varies inside the :FETCH and :STORE subs? Would they close
> over $?SELF, too?
Yes, just like when you say `my $self = shift` in Perl 5. $self is closed over.
> If they did, doesn't this mean that $var will be a new Proxy attribute
> every time that the attribute is read, and will have side effects?
Well, your implementation has side-effects whether or not it's a new
Proxy every time.
> Such as;
>
> my $foo = MagicVal.new();
> $foo.varies = 5; # sets to 6;
> say $foo.varies; # says 8
> say $foo.varies; # says 10
Yep.
> my $var = $foo.varies; # $var is proxy for attribute
> say $foo.varies; # says 12
> say $var; # says 14
Nope. The `is Proxy` is a trait on the *container*. The container
does not pass through scalar assignment. If you bound using :=
instead in the first line of this quote, then the semantics you
describe would occur.
> It seems to me that the only time I'd want to actually return a
> Proxy object is when taking a reference to the fake attribute. In
> all other situations, you'd simply want to dispatch to either an
> accessor or a mutator, depending on the context.
That is precisely what will happen. It falls out of the semantics of
tied containers.
> ie, I'd like the design of this feature to be sufficient that most
> of the time, the Proxy object need never be constructed, and instead
> the relevant closure could be bound to that method instead.
I expect that it might be possible to optimize away such a proxy
object in non-referential context. The sub checks its context: if it
is lvalue, then it immediately calls the STORE method. If it is
rvalue, it immediately calls the FETCH method. However, as far as I
can tell, this optimization requires that Perl know about the Proxy
class in particular.
> In particular, I think this would mean making Proxy objects
> automatically call FETCH when returned, unless in reference context.
>
> In fact, I think I'd rather see the proxy as a closure trait;
>
> class MagicVal {
> has Int $.varies is rw;
>
> method varies returns Int is Proxy( :FETCH(&get_varies),
> :STORE(&set_varies) );
But other than that it looks good. I would name the trait something
other than Proxy probably. Perhaps `accessor`.
Luke