in reply to Mixed lvalue/rvalue sub function

I'm certainly not a guru, and didn't even knew or realized that 'lvalue' exists. So thanks for bringing it up :)

Aside from that, just my opinion: That kind of API is quite weird. I usually write such methods like you did, with an optional $value argument. I guess what I dislike about that lvalue API is, that it looks like action at a distance when skimming through code:

my $v = $self->header ('test') = "fail"; # :-)
vs.:
my $v = $self->header ('test', 'fail');

When you skim over the second example you immediately recognize the missing closing ')'. Of course the first example is also an example of bad formatting, so this might not be an actual issue. I'm just not used to assigning to subroutines.

But that aside: Did you think about returning object handles where you overload the '='? In C++ that is done quite often. Then even this would work:

my $hdr_slot = $self->header ('test'); $hdr_slot = "new value"; # Set print "New header: $hdr_slot\n"; # Get

Replies are listed 'Best First'.
Re^2: Mixed lvalue/rvalue sub function
by mscharrer (Hermit) on Apr 18, 2008 at 13:38 UTC
    Hi, I realize that the lvalue syntax looks a little weird, maybe I should kick it out and just have:
    $obj->header('test'); # Get header 'test' $obj->header('test','new value'); # set header test $obj->header; # Get all headers as hash
    You C++-ish suggestion:
    my $hdr_slot = $self->header ('test'); $hdr_slot = "new value"; # Set print "New header: $hdr_slot\n"; # Get
    doesn't work in Perl because there all objects are references (to talk C++: from type *myclass not myclass). So assigning to $hdr_slot would make this variable a string with the value "new value" and would remove the reference to the object. Overloading the '=' operator only is used for generating temp copies for operators like '+=', so far I know.

    The only way to do this is to tie a class to $hdr_slot. Then you can define a STORE method which gets called at every '='. See 'perldoc perltie' for more.

    I read all this in the book 'Object Oriented Perl' just two weeks ago.

      Ah, yes, you are of course completely right, I guess I did too much C++ recently :)

      Alternatively you could return a reference to the header, of course. But it would look kinda more ugly than the simple optional argument solution:

      my $slot = $self->header ('test'); $$slot = "New value"; print "Value for header: $$slot"; # or even $slot, if you overload the + stringification
        If you like to start using lvalue function, you should know that they are still marked as experimental (at least in Perl 5.8).

        perlsub says:

        WARNING: Lvalue subroutines are still experimental and the implementation may change in future versions of Perl.