http://www.perlmonks.org?node_id=223918


in reply to Re: $foo->bar = 14;
in thread $foo->bar = 14;

I think it's a mistake to confuse "experimental" as a synonym for "doesn't work properly yet".

For me experimental means:

  1. Might have bugs - probably not true for :lvalue, the current implementation seems pretty solid
  2. Might change in a non-upward compatable manner - more likely for :lvalue if it is going to be of much use
  3. Might not be the "right" way of doing it - in my opinion the current :lvalue opens up your object implementation details far to much and is not the "right" way :-)

I would not use :lvalue in production code because of (2) and (3). See lvalue considered harmful... where I go into this in more boring detail :-), and a suggestion for how I would like it to work.

One of the benefits of using subroutines instead of direct hash access is that you can catch typos easily. If you assign to $self->{elemnent} you're missing the mark quietly, but a call to $self->elemnent will outright fail.

I agree, but I think the disadvantages of :lvalue more than outweigh this advantage (and there are other ways to get around typos - e.g. inside out objects or Tie::SecureHash.)

Replies are listed 'Best First'.
Re: $foo->bar = 14;
by tadman (Prior) on Jan 03, 2003 at 02:44 UTC
    I think the aversion to using lvalue subroutines is cultural. I'm quite used to putting data, any data, into a C struct, or a C++ class object. You can shoot yourself in the foot, of course, but that's why you have to be careful.

    At least superficially, lvalue subroutines feel a lot more like they're real, tangible things, and not some fleeting whim of a hash key. Yes, you can put in bad data, yes you can break things, but putting rubber pads on the edge of all of your functions does not make them safe. It's just defensive programming, which in many cases is dangerous if over-done.

    As far as I can tell, lvalue works fine now, and when it's replaced with something better in Perl 6, which surely it will be, then there's no reason not to upgrade.

    One could just as easily argue that Perl 5 is experimental. Your points 1, 2, and 3 all apply to the same degree.
      I think the aversion to using lvalue subroutines is cultural

      Not in my case :-) I came to perl after doing a lot of coding in Pop-11 and I still miss its "updaterof" idiom.

      I would like being able to do $o->foo = 12 in my perl modules. It makes it explicit when a method is a mutator without the noise of having separate setter/getter functions.

      Unfortunately (in my opinion) the perl implementation of lvalue subs is near useless since it exposes the object implementation - making it harder to change your module

      Yes, you can put in bad data, yes you can break things, but putting rubber pads on the edge of all of your functions does not make them safe.

      Nothing can make your code 100% safe :-) Having assertions on arguments, etc. can certainly make it a lot safer. It can cut development time on larger projects by a silly amount - because you get sane errors close to the location that caused them.

      It's just defensive programming, which in many cases is dangerous if over-done.

      I agree, but I see it under-done a lot more than I see it over-done.

      However, the point I was trying to make wasn't about checking arguments - it was about exposing the implementation of your class.

      For example, consider a hypothetical object that can be readable, writeable or locked. With an :lvalue based API you would have something like this:

      my $o = Foo->new; $o->locked = 1; $o->writeable = 0; $o->readable = 1;

      Now, what happens if (for whatever reason) I want to change the underlying implementation of these attributes to use a bitmask. You either have to change your API - or create some ghastly hack with tie. This is what I mean by an over-exposure of your object's implementation.

      With a traditional single accessor/mutator or separate setter/getter methods - no problem.

      As far as I can tell, lvalue works fine now, and when it's replaced with something better in Perl 6, which surely it will be, then there's no reason not to upgrade.

      Hmmm... I wonder if you could do something sane now with the aid of tie and some source filters.... I'll have to have a think when I get some spare time...

      One could just as easily argue that Perl 5 is experimental. Your points 1, 2, and 3 all apply to the same degree.

      Got to disagree with that completely. They do not apply to the same degree. Experimental features break on a regular basis (threads, some of the regex stuff, etc.). Core perl has been very solid - due to lots of care and attention by the wonderful development peeps. I've had perl4 scripts run on 5.8 without a single change.

      The 5.8 release especially has had a lot of time spent on a very nice test suite to prevent regression problems.


      Update: Cleaned up the English a little.

        You don't have to change your API, or use a tie, at least in this case. Something like this, perhaps:
        sub read : lvalue { my ($self) = @_; vec($self->{value},0,1); }
        I know it's not pretty, but it works.

        I didn't mean to say that Perl hasn't worked very well for me, but there are occasions where it has been broken, though admittedly these were in the early days of Perl 5. So far, Perl 5.8 has been wonderful, too, so less experimental than ever before, perhaps.