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

Return a tied object as an lvalue. Here's a quick sample using a DBM:
dbmopen %FOO, "my_database", 0644 or die; ... sub foo :lvalue { my $self = shift; $FOO{$self->key}; } ... my $obj = SubClass->new; $obj->foo = 35; # calls tied(%FOO)->STORE($obj->key, 35); my $fetch = $obj->foo; # calls tied(%FOO)->FETCH($obj->key);
Change the tie package as needed.

-- Randal L. Schwartz, Perl hacker

Replies are listed 'Best First'.
Re^4: Uses for an lvalue subroutine
by Velaki (Chaplain) on Jul 30, 2004 at 19:49 UTC
    For me, I found that the lvalue allows me to implement accessor functions in a more intuitive manner, such as in the ring memory model, below.
    # ------------------------------------------------------- # Ring.pm : memory ring model for CW # Author : Velaki (velaki@aol.com) # Date : 09 July 2004 # Version : 1.0 # History : # # 1.0 09 July 2004 -- added init routines <Auth> # 0.2 09 July 2004 -- converted set/get to cell <Auth> # 0.1 08 July 2004 -- initial version <Auth> # # ------------------------------------------------------- package Ring; require Exporter; @ISA = qw/Exporter/; @EXPORT = qw//; @EXPORT_OK = qw//; $VERSION = 1.0; use strict; my $DEFAULT_SIZE = 10; # Default ring size for memory ring. # ------------------------------------------------------- # Name : new # Desc : create a new memory ring # # Input : size to make memory ring, or none # Output: new memory ring segment # sub new { my $this = shift; my $class = ref($this) || $this; my $size = shift || $DEFAULT_SIZE; my $self = { SIZE => $size, RING => [] }; bless $self, $class; $self->init; return $self; } # ------------------------------------------------------- # ------------------------------------------------------- # Name : init # Desc : blank the ring memory # # Input : none # Output: none # sub init { my $self = shift; $self->cell($_) = 0 for (0 .. $self->size); } # ------------------------------------------------------- # ------------------------------------------------------- # Name : size # Desc : get the size of the ring # # Input : none # Output: the size of the ring # sub size { my $self = shift; return $self->{SIZE}; } # ------------------------------------------------------- # ------------------------------------------------------- # Name : cell # Desc : get or set the value of a ring cell # # Input : address to be set/retrieved # Output: the current value at the address # sub cell : lvalue { # making it an lvalue means # we can set it during # retrival, e.g. # $c->cell(3) = 10; # print $c->cell(3); # prints: 10 my $self = shift; my $addr = shift; # the address is normalized before being used $self->{RING}[$self->naddr($addr)]; } # ------------------------------------------------------- # ------------------------------------------------------- # Name : naddr # Desc : Normalize ring address to a positive number. # # Input : signed integer address # Output: unsigned address guaranteed to fit in ring # sub naddr { my $self = shift; my $addr = shift; return $addr % $self->size; } # ------------------------------------------------------- 1; # end of module
    This way, I can grab a ring instance, and use the accessor functions as follows:
    use Ring; my $r = Ring->new(); $r->cell(4)="142"; print $r->cell(4),"\n";
    This way, I don't have to think so much about accessing this particular member function.

    I hope that it remains a permanent feature of the language. -v.