Nathan Torkington wrote:
>
> Not every subroutine corresponds to a method call exposing
> object-internal data. Most of my subroutines *do* something and make
> no sense to be called lvaluably. Explicit marking the compiler pick
> up assignments to non-lvaluable subroutines. It makes sense to
> explicitly mark the rare cases (:lvalue), rather than the common
> (:no_assignment).
Well, this argument makes more sense. However, I still have to disagree.
In fact, I think the opposite: ALL subs *should* be lvaluable by
default. Here's why.
One word: CPAN (ok, an acronym :). Let's take CGI.pm as an example.
Currently, you can do this:
$val = $cgi->param($name); # get the param
$cgi->param($name, $val); # assign a val
So, it seems the next logical extension would be this:
$cgi->param($name) = $val; # assign a val
No problem. In fact, this fits under your rules. HOWEVER, it also
assumes that Lincoln thought that param() was :lvalue-worthy. What if he
forgot? Or didn't think of this case?
Worse, what if a somewhat novice writes a module and doesn't know about
:lvalue, or at least not how to use it. But an experienced user picks up
their module DoCoolStuff.pm on CPAN and tries it:
use DoCoolStuff;
$dcs = new DoCoolStuff;
$dcs->main_matrix_name = "Bob";
Ooops! The author didn't use :lvalue. So even though this makes perfect
sense to be able to do, since the author forgot to use :lvalue, you lose
a really cool syntactic tool. This seems backwards. I, the user, want to
make this decision. There's no way a module author can possibly forsee
all the uses of a function, and they shouldn't have to.
Having lvalue subs that work just like rvalue ones is an invaluable
tool. This RFC is right on. The only way, though, that it's going to be
useful is if it works just like other assignment: automatically and
pervasively. For one thing, you can do this:
@array = $r->func((split /:/, <PASSWD>));
Why not this?
@array = ($r->func) = split /:/, <PASSWD>;
Might look weird at first, but it's not. It's just like any other
assignment. This surely doesn't look weird:
@array = ($r->{func}) = split /:/, <PASSWD>;
And it works just fine in default Perl 5 with no special keywords. No
reason that dropping two {}'s should change this. If it does, then we're
losing valuable OO encapsulation and abstraction. In fact, a lot is
gained in making lvalue subs the default, because it makes things more
reliable and consistent.
lvalue subs are worth a lot more than just simple data accessor
functions. I don't see why we should force-relegate them to a background
role by requiring an :lvalue constraint that most people won't
understand how to use correctly. This is a perfect opportunity to make
an easy thing even easier.
-Nate