in reply to Re^3: Perl OO and accessors
in thread Perl OO and accessors

What you do with $c->set_area( -42 )?

Maybe I'm missing something. Say that I implemented set_area as

sub set_area { my $self = shift; my $area = shift; die "Area must be non-negative." unless $area >= 0; # ... }
How do you do the same with an lvalue sub?

How do you go back and change the interface later to avoid set_foo methods?

You don't. But, that's okay because you never have a need to.

-sauoq
"My two cents aren't worth a dime.";

Replies are listed 'Best First'.
Re^5: Perl OO and accessors
by Aristotle (Chancellor) on Nov 29, 2005 at 04:36 UTC

    How do you do the same with an lvalue sub?

    You return a tied value. Ugly, slow, and doable. fergal did say <q>Neither of these expose an attribute, despite how it looks.</q>

    You don’t. But, that’s okay because you never have a need to.

    Why then would I ever have a need to go back and avoid lvalue subs?

    Makeshifts last the longest.

      As Ovid once put it:

      Of course, some lvalue fans argue that I can use tie to get my validation back. Great! Now I've lost much of the conciseness I've hoped to gain and I've probably moved the data validation code away from the method in which the maintenance programmer expects to see it but at least I've switched to a slow, confusing and fragile interface!

      -sauoq
      "My two cents aren't worth a dime.";
      
        Ovid's beating a straw man in that quote. Nobody is suggesting that everyday you should bash out lots of awful code directly involving tieing. Would yourself and Ovid also object to exporting values and functions because it involves advanced symbol table poking? Of course not, it's all hidden behind Exporter. Most users don't know how it works at all.

        The same goes for lvalue+tie. As I said in another post there's Class::Accessor::Lvalue. Personally I use my own home brew module which lets me say

        package Circle; use Fergal::MM qw( Radius Area ); # this creates # setRadius, getRadius, Radius # setArea, getArea, Area # # All are created in Circle::Accessors and Circle's @ISA # is updated to include Circle::Accessors. # This makes overriding easy. # now override the Area ones sub setArea { my ($self, $area) = @_; $self->Radius = sqrt($area/PI); } sub getArea { my ($self, $area) = @_; my $r = $self->Radius; return PI * $r * $r; }

        This removes all but one of Ovid's complaints - it's probably slow but if you really need speed then you can just ignore the lvalue interface and use the set/get methods directly. I think I benchmarked it as a factor of 10 slower but how much of your code is accessor calls? If you really need speed, Perl OO is probably not what you want.

        C’mon now, what do you expect me to say? Don’t use Perl5 OO? :-)

        Wait. Perl6 is right around the corner.

        Or maybe… Have you heard of Ruby?

        Seriously, though, things like Tie::Constrained take most of the pain away. Sure, I’d rather there was a better way, too. In any case, as a user of APIs with lvalue accessors I quite liked them; I haven’t so far actually designed an API with lvalue subs myself, however.

        Basically, the ugliness involved in lvalue accessors is just one more thing that makes me go “okay, I have appreciated the beauty and elegance in Perl5’s ultra-minimal OO approach enough, but now I’d like to get some real work done.”

        But all these considerations apply to the hidden end of an API. From the public side, lvalue accessors have no downsides whatsoever. They don’t expose anything untoward. That’s what I was arguing.

        Makeshifts last the longest.

      I was going to /msg you with "and don't use tie" but you beat me to it.

      You return a tied value. Ugly, slow, and doable.
      Why then would I ever have a need to go back and avoid lvalue subs?

      Perhaps when you decide you need validation without an ugly and slow (but doable) implementation?

      -sauoq
      "My two cents aren't worth a dime.";