How to make "universal" getters and setters in an object in perl? -
how make 1 setter method, , 1 getter method manage access fields of object? new subroutine looks this:
sub new { $class = shift; $self = {@_}; bless($self,$class); # turns object } creation of new object looks this:
$foo = package::new("package", "bar", $currentbar, "baz", $currentbaz, );
this not idea.
perl instituted use of use strict; take care of problems this:
$employee_name = "bob"; print "the name of employee $employeename\n"; mistyped variable names common problem. using use strict; forces declare variable, errors can caught @ compile time.
however, hash keys , hash references remove protection. thus:
my $employee[0] = {} $employee[0]->{name} = "bob"; print "the name of employee " . $employee[0]->{name} . "\n"; one of reasons use objects when start talking complex data structures prevent these types of errors:
$employee = employee->new; $employee->name("bob"); print "the name of employee " . $employee->name . "\n"; this error caught because method name name , not name.
allowing users create own methods @ random removes protection using objects:
$employee = employee->new; $employee->name("bob"); #automatic setter/getter print "the name of employee " . $employee->name . "\n"; #automatic setter/getter now, because of automatic setters , getters, fail catch error because method user names valid -- if user made mistake.
in fact, setup objects object doesn't know how it's structured. observe following class methods foo , bar:
sub new { $class = shift; $foo = shift; $bar = shift; $self = {}; bless $self, $class; $self->foo($foo); $self->bar($bar); return $self; } sub foo { $self = shift; $foo = shift; $method_key = "foo_foo_foo_barru"; if (defined $foo) { $self->{$method_key} = $foo; } return $self->{$method_key}; } sub bar { $self = shift; $bar = shift; $method_key = "bar_bar_bar_bannel"; if (defined $bar) { $self->{$method_key} = $bar; } return $self->{$method_key}; } i can set class values foo , bar in constructor. however, constructor doesn't know how values stored. creates object , passes along getter/setter methods. nor, 2 methods know how store each other's value. that's why can have such crazy names method's hash keys because available in method , no else.
instead, methods foo , bar both setters , getters. if give them value foo or bar, value set. otherwise, return current value.
however, i'm sure know of , insist must done. well...
one way of handling want create autoload subroutine. autoload subroutine automatically called when there's no other method subroutine name. $autoload contains class , method called. can use setup own values.
here's test program. use 2 methods bar , foo, use methods , still work fine
one change, use parameter hash in constructor instead of list of values. no real difference except considered modern way, , want consistent else does.
also notice normalize method names lowercase. way $object->foo, $object->foo, , $object-foo same method. way, @ least eliminate capitalization errors.
use strict; use warnings; use feature qw(say); use data::dumper; $object = foo->new({ -bar => "bar_bar", -foo => "foo_foo", } ); "foo: " . $object->foo; "bar: " . $object->bar; $object->bar("barfu"); "bar: " . $object->bar; dumper $object; package foo; sub new { $class = shift; $param_ref = shift; $self = {}; bless $self, $class; foreach $key (keys %{$param_ref}) { # may or may not leading dash or dashes: remove them (my $method = $key) =~ s/^-+//; $self->{$method} = $param_ref->{$key}; } return $self; } sub autoload { $self = shift; $value = shift; our $autoload; ( $method = lc $autoload ) =~ s/.*:://; if ($value) { $self->{$method} = $value; } return $self->{$method}; }
Comments
Post a Comment