in reply to Re: (tye)Re: Uses for an lvalue subroutine
in thread Uses for an lvalue subroutine

You use $self->{foo}, of course.

When using inheritance, you don't treat your ancestors as black boxes (well, if you are doing inheritance of APIs, then you do, but Perl doesn't natively support inheritance of APIs anyway).

Of course, if the SuperClass::foo() is very complex or you just want to write an inefficient subclass, then you can use $self->SUPER::foo() instead.

So using :lvalue methods in a class doesn't really change anything about inheritance.

        - tye (but my friends call me "Tye")

Replies are listed 'Best First'.
Re: (tye)Re2: Uses for an lvalue subroutine
by gildir (Pilgrim) on Jan 10, 2001 at 21:36 UTC
    I dont think so.
    Look at my example in previous reply. In SuperClass, attributes are stored in blessed hash, that means in object itself. But now I want to write a 'persistent' object, and I want attributes to be stored in some kind of persistent storage (database) instead of hash.
    I suppose SuperClass has many methods, all of them deal with $self->foo like a lvalue, using $self->foo = 123;.

    And now, how to write SubClass that will store foo attribute in database? If I have 'traditional' $self->foo(123) method, solution is trivial. But with lvalue methods I cannot do such a thing.

    It is never a good practice to make any assumption about storage of object attributes in strict OOP. For this reason we use $self->foo instead of $self->{foo}.

      Oh, I see what you are complaining about now.

      But I disagree that inheritance should generally be used to override how an object's members are stored. I don't advocate using get/set methods to access members when within the object's methods, unless you specifically designed those members to be overridden. But I agree with your point that if you've made that decision, then using the current implementation of :lvalue subs might be something to avoid.

      I'd also avoid updating the RDMS for every single attribute assignment, caching the attributes in a hash and then flushing to the DB at destruction time, when requested, and/or at designed-in synchronization points.

      Using a tied reference (like merlyn suggests) crossed my mind but it seem like a pretty big hammer to use (quite a bit of overhead and coding required).

      An alternate work-around is:

      my %TempMap; sub foo :lvalue { my $self= shift; my $value= $self->fetch("foo"); $TempMap{"".\$value}= [$self,"foo"]; return bless My::Module::Value, \$value; } sub My::Module::Value::DESTROY { my $svValue= shift; my( $self, $name )= @{ $TempMap{$svValue} }; $self->store( $name, $$svValue ); }
      Which gets me to wondering how inheritance of :lvalue methods could be improved to avoid using tie to separate the code for fetching from storing (because I'd really like to provide a :lvalue interface to my members).

              - tye (but my friends call me "Tye")