Limbic~Region has asked for the wisdom of the Perl Monks concerning the following question:
All,
Today, perldeveloper (a new monk) asked in the CB if it was possible to make class method that can both set and get a value, but with post and pre-processing like C#. The following example was given:
So - is there a better way of doing this? Is it hard to extend Attribute::Property to do what perldeveloper wanted? 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?
Today, perldeveloper (a new monk) asked in the CB if it was possible to make class method that can both set and get a value, but with post and pre-processing like C#. The following example was given:
I remembered Zaxo's post on validating data in lvaluable subs and that one of the replies mentioned it duplicating the work of Attribute::Property. After reading the POD, I realized that it doesn't quite fit the bill:$obj->Name = "My Name"; print $o->Name, "\n"; # "My Name, post processed".
Your object must be a blessed hash reference. In short: $foo->bar = 14 and $foo->bar(14) assign 14 to $foo->{bar} after positive validation.
It limits the object type to a hash reference (which is most common), but then doesn't actually provide hooks for pre/post "processing". I came up with the following: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";
Cheers - L~R
Update: Modified code to accept a code ref for pre/post hook instead of hardcoded
|
---|
Back to
Seekers of Perl Wisdom