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