On 2008-Jun-2, at 3:30 pm, Jon Lang wrote:
sub foo($value?) is rw($value) { ... }
Or something to that general effect. The parameter in question must
be optional and cannot have a default value, so that a test of
whether or not the parameter is actually there can be used to
determine whether or not to operate like FETCH or like STORE.
I like "is rw($value)". There does need to be a way to tell whether a
value was passed to it, even if that value was undef. Ah, it just
occurred to me that rather than checking the $value, you should be
able to check "want~~:($ is rw)".
Does this [with no slurpy scalar to pick up the rvalue]:
sub foo () { ...; $proxy }
give us anything that you couldn't get from:
sub foo ($rval is rvalue) { ...; $proxy = $rval }
(I'm assuming that both of these subs are rw.)
Yes. infix:<=> isn't the only operator that assigns values to rw
objects: so do the likes of infix:<+=> and prefix:<++>. As well,
any function that accepts a rw parameter will presumably end up
writing to it somewhere in its code; otherwise, why declare the
parameter as rw?
I would expect all of those to work the same way in either case. That
is, anywhere the sub is used as an lvalue, it could pass the rvalue as
a special arg, not just when using "=".
Note, BTW, the difference between passing a proxy object as a
parameter and passing a mutating sub as a parameter: in the former
case, you call the lvalue sub once in order to generate the proxy
object, and then you pass the proxy object as a parameter; in the
latter case, you don't call the mutating sub: you essentially pass a
coderef to it, and then call it each time the function in question
attempts to read from or write to it.
OK; but I think that can be handled by a mutating sub -- assuming the
issue is that the proxy-sub "sub foo is rw { blah; $proxy }" runs
"blah" once and returns the proxy that can be assigned to multiple
times, whereas a mutating sub would run "blah" every time you use it.
But:
sub foo is rw($rval) { unless want~~:($ is rw) { blah }; $unproxy=
$rval; }
In other words, the mutating-sub-way can do everything the proxy-way
can (and more), as long as we can tell when being used in lvalue-
context.
Incidentally, now that Perl is all OO-y, do we need tying/proxying
like
that, or can we just override the "=" method on a class instead?
It's possible that in perl6, 'STORE' could be spelled 'infix:<=>';
but then how would 'FETCH' be spelled? And doing so would require
that your storage routine return a value, even if you never intend
to use it. No; I prefer 'STORE' and 'FETCH' as the basic building
blocks of anything that's capable of working like a rw item.
I agree with that; I'm just pondering whether we need the concept of
"tying" any more, or whether FETCH and STORE can be thought of as
standard methods for any object. In P5, not everything was an object,
but everything is in P6 (or can be considered one, if you like
objects), so it would be simpler to think in terms of one unified
concept instead of two.
Of course, since subs are objects too, maybe all you need for an
lvalue-sub is to override the FETCH and STORE methods it already has.
But then the "is rw" stuff would simply be syntactic sugar to make
doing so prettier.
-David