On Fri, Apr 23, 2004 at 03:23:09PM -0400, Austin Hastings wrote:
: > And if you override the accessor, you can:
: >
: >     multi method foo(Str $blah = undef) is rw($new) {
: >             (my($old),$.foo)=($.foo,$blah//$new);
: >             .update_the_world_in_some_cool_way();
: >             return $old
: >     }
: 
: I don't understand this.

It's what we on the cabal have been calling an out-of-band parameter.
We have at times contemplated them for various purposes, none of
which seem to have panned out.  Instead we've ended up with things
like $CALLER::_ and such.

: What's the $new doing?

It looks to me like it's being a parameter that doesn't interfere
with the official signature.

: And if you've only got one of them, do you need multi, or just an optional
: argument?

It's just an optional argument, but...

: method foo(Str ?$new) is rw {
:   my $old = $.foo;
:   if (defined($new)) {
:     $.foo = $new;
:     .update_the_world();
:   }
:   return $old;
: }

...but it doesn't ruin the signature symmetry between getter and
setter like yours.  It does share the misfeature that you have to
write special switching code internally to deal with it, which the
proxy solution automatically dispatches for you.  It also assumes
you even want the old value, which you often don't, if the proxy is
destined to be the left side of an ordinary assignment in void context.
And, in fact, if it weren't in void context, you'd want the new value,
not the old one, which means you better hang onto that proxy...

I suppose in the cases where the attribute can serve as its own proxy,
we could have a hook that captures control on setting, and lets you
add side effects en passant without making you responsible to actually
set the variable like a STORE hook would.  If you wanted to remove the
actual attribute you'd have to graduate it to a STORE closure on a
real proxy though (with whatever syntactic sugar makes that most
palatable).

Larry

Reply via email to