How do I name a function name stored in a hash in Perl?

I am sure that this is described in the documentation, but I could not find it ... I am looking for syntactic sugar that will allow a method to be called in a class whose name is stored in a hash (as opposed to a simple scalar):

use strict; use warnings; package Foo; sub foo { print "in foo()\n" } package main; my %hash = (func => 'foo'); Foo->$hash{func}; 

If I first copy $hash{func} into a scalar variable, then I can just call Foo->$func ... but what is missing to enable Foo->$hash{func} ?

(EDIT: I'm not going to do anything special by calling the method of the Foo class - it can be an easy and blessed object (and in my actual code), it was just easier to write a standalone example using the class method.)

EDIT 2: Just for the sake of completing the comments below, this is what I am actually doing (this is in the Muse sugar attribute library created using Moose :: Exporter ):

 # adds an accessor to a sibling module sub foreignTable { my ($meta, $table, %args) = @_; my $class = 'MyApp::Dir1::Dir2::' . $table; my $dbAccessor = lcfirst $table; eval "require $class" or do { die "Can't load $class: $@" }; $meta->add_attribute( $table, is => 'ro', isa => $class, init_arg => undef, # don't allow in constructor lazy => 1, predicate => 'has_' . $table, default => sub { my $this = shift; $this->debug("in builder for $class"); ### here the line that uses a hash value as the method name my @args = ($args{primaryKey} => $this->${\$args{primaryKey}}); push @args, ( _dbObject => $this->_dbObject->$dbAccessor ) if $args{fkRelationshipExists}; $this->debug("passing these values to $class -> new: @args"); $class->new(@args); }, ); } 

I replaced the marked line above:

  my $pk_accessor = $this->meta->find_attribute_by_name($args{primaryKey})->get_read_method_ref; my @args = ($args{primaryKey} => $this->$pk_accessor); 

PS. I just noticed that the same technique (using the Moose metaclass to search for a codeword, rather than accepting its naming convention) cannot be used for predicates either, since Class :: MOP :: Attribute does not have a similar accessory get_predicate_method_ref .: (

+8
syntax reference perl attributes moose
02 Dec '09 at 22:06
source share
3 answers
 Foo->${\$hash{func}}; 

But for clarity, I will probably still write it like:

 my $method = $hash{func}; Foo->$method; 
+14
Dec 02 '09 at 22:35
source share

Is there a reason you store subroutine names instead of code references?

eg.

 use strict; use warnings; package Foo; sub foo { print "in foo()\n" } package main; my %hash = (func => \&Foo::foo); $hash{func}->(); 

You will not pass the class name, but if that matters to you, you can use something like

 my %hash = ( func => sub { return Foo->foo(@_) } ); 
+2
Dec 02 '09 at 22:13
source share

Have you tried UNIVERSAL ? You should implement something like this:

 ## untested if ( my $code = $object->can( $hash{func} ) ) { $object->$code(); } 

I made a useless single line example to demonstrate:

 perl -MData::Dumper -le 'my %h = ( f => "Dump" ); my $o = Data::Dumper->new( [qw/1 2 3/] ); my $ref = $o->can( $h{f} ); print $o->$ref()' 
+1
Dec 03 '09 at 20:33
source share



All Articles