Your functions in the dispatch table are closures over $self
. If you pass in the $self
as a parameter, you can get around that. Note that state
variables are not true closures over $self
, and would require an explicit parameter as well.
my %funcs = (
a => sub { shift->_a }, # these are like anonymous methods
b => sub { shift->_b },
);
sub foo {
my ($self, $var) = @_;
my $meth = $funcs{$var} || die "There is no entry $var";
return $self->$meth(); # sugary syntax
}
Here is a demonstration why state
would be a bad idea:
use 5.010;
package Foo;
sub new { my ($c, $v) = @_; bless \$v, $c }
sub foo {
my ($self) = @_;
state $cb = sub { say $$self };
$cb->();
}
Foo->new($_)->foo for 1..3;
Output:
1
1
1
The inner sub is a closure, but the initialization of $cb
is only performed once. Thus the closed over $self
is the first one.