Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Limbic Region (3985)

Limbic Region
  (email not shown publicly)
http://gatcomb.org/joshua/perl.html

I love to code perl. If you want to hire me, see details on my homepage.
Thursday June 24, 2004
11:47 AM

Extending LValuable Subs with Tied Variables

[ #19470 ]

Sort of crossposted from:
http://www.perlmonks.org/index.pl?node_id=369354

A new monk at the Monastery wanted to be able to use the following syntax to get/set properties

my $name = $obj->name;
$obj->name = "Limbic";

Ok - use an lvaluable sub right. Well the new monk also wanted to be able to pre/post process like C# (which I don't have any knowledge of):

$obj->name = "Limbic";
print $obj->name, "\n"; # "Limbic post processed"

After getting nowhere trying to convince the monk to use the conventional syntax, I decided to give it a shot. I came up with the following in about 20 minutes (I had never used lvaluable subs before and have only used tied variables a few times)

package magic;

sub TIESCALAR {
        my $class = shift;
        die "Incorrect number of parameters" if @_ % 2;
        my $self = bless {}, $class;
        $self->_Init(@_);
        return $self;
}

sub _Init {
        my ($self, %opt) = @_;
        $self->{PRE} = $opt{PRE} || sub { return uc $_[0] };
        $self->{POST} = $opt{POST} || sub {
                my $val = shift;
                $val =~ s/FOO/BAR/;
                return $val;
        };
        return;
}

sub STORE {
        my ($self, $value) = @_;
        $value = $self->{PRE}->( $value );
        $value = $self->{POST}->( $value );
        $self->{VAL} = $value;
}

sub FETCH { return $_[0]->{VAL} }

########################################

package cool;

sub new {
        my $class = shift;
        tie my $name, "magic", @_;
        bless \$name, $class;
}

sub name :lvalue {
        ${$_[0]};
}

########################################

package main;

tie my $string, "magic";
$string = 'My left foot';
print "$string\n";

my $obj = cool->new( 'POST' => sub { return reverse $_[0] } );

$obj->name = "My right foot";
print $obj->name, "\n";

I posted the following questions after the response:
Is there a better way of doing this?
Is it hard to extend Attribute::Property to do this?
If this is the way to do it, how can it be wrapped up in a module like Attribute::Property to make it easier to use?

Since I haven't (as of yet) gotten any feedback at the Monastery I figured I would throw it out here as well.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.