Variable containing name of function inside a package

P

pmak00

How can I get this piece of code to work?

my $name = 'hello';
&Hello::$name();

I want the second line to do the equivalent of Hello::hello().
 
A

A. Sinan Unur

(e-mail address removed) wrote in @z14g2000cwz.googlegroups.com:
How can I get this piece of code to work?

my $name = 'hello';
&Hello::$name();

I want the second line to do the equivalent of Hello::hello().

Why?

perldoc -q "How can I use a variable as a variable name?"

#! /usr/bin/perl

use strict;
use warnings;

package Hello;

sub hello {
print "Hello\n";
}

sub goodbye {
print "Goodbye\n";
}

package main;

my %handlers = (
hello => \&Hello::hello,
goodbye => \&Hello::goodbye,
);

$handlers{hello}->();
$handlers{goodbye}->();

__END__
 
G

Gunnar Hjalmarsson

How can I get this piece of code to work?

my $name = 'hello';
&Hello::$name();

I want the second line to do the equivalent of Hello::hello().

&{ \&{ "Hello::$name" } };
 
T

Tad McClellan

How can I get this piece of code to work?


How about if you can get what you want and abandon this piece of code?

my $name = 'hello';
&Hello::$name();

I want the second line to do the equivalent of Hello::hello().


Use a "coderef" (instead of the horrid "symbolic ref"):

my $func = \&Hello::hello;
$func->();

If you have many funcs, then put them into a hash instead of a scalar:

$funcs{hello} = \&Hello::hello;
$funcs{hello}->();
 
B

Brian McCauley

Gunnar said:
&{ \&{ "Hello::$name" } };

That's not what the OP asked for, you forgot the ().

But I think it's better to be open and honest about the fact that you
are using symrefs rather than using a loophole to disguise the fact.

{
no strict 'refs';
"Hello::$name"->();
}
 
G

Gunnar Hjalmarsson

Brian said:
That's not what the OP asked for, you forgot the ().

Okay.

( \&{ "Hello::$name" } )->();
But I think it's better to be open and honest about the fact that you
are using symrefs rather than using a loophole to disguise the fact.

I don't understand. Where is the symref?

my $hardref = \&{ "Hello::$name" };
$hardref->();
 
A

Anno Siegel

Gunnar Hjalmarsson said:
Okay.

( \&{ "Hello::$name" } )->();


I don't understand. Where is the symref?

my $hardref = \&{ "Hello::$name" };
$hardref->();

&{ "Hello::$name" } is a symref. It accesses the package stash at
run time.

Anno
 
G

Gunnar Hjalmarsson

Anno said:
&{ "Hello::$name" } is a symref. It accesses the package stash at
run time.

Well, I hear what you say. I'm disinclined to accept something I don't
understand just because two authorities states it, but in this case I'm
ready to make an exception. ;-)

Thanks!
 
B

Brian McCauley

Tad said:
Use a "coderef" (instead of the horrid "symbolic ref"):

my $func = \&Hello::hello;
$func->();

If you have many funcs, then put them into a hash instead of a scalar:

$funcs{hello} = \&Hello::hello;
$funcs{hello}->();

If the all the functions in the package Hello are going to be in %funcs
(and vice versa) then %funcs and %Hello:: are just a duplication of effort.

Such duplication of effort is bad. Worse even than symrefs.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,172
Messages
2,570,933
Members
47,472
Latest member
blackwatermelon

Latest Threads

Top