Function alias

N

neilsolent

I have a question on Perl syntax. Given a couple of functions:

#########
sub Test1
{
print "Test1\n";
}

sub Test2
{
print "Test2\n";
}

#######

How can I call the subroutine that is named in a scalar variable
$func?
Here, the scalar $func will contain either "Test1" or "Test2"

e.g. this doesn't work:

&($func)

Thanks,
Neil
 
J

Jürgen Exner

neilsolent said:
How can I call the subroutine that is named in a scalar variable
$func?
Here, the scalar $func will contain either "Test1" or "Test2"

One quick and dirty way: use eval(), which of course comes with its own
load of risks and issues.

The best way is to use a dispatch table, see DejaNews aka Google Groups
for details, this has been discussed before.

jue
 
T

Tad J McClellan

neilsolent said:
I have a question on Perl syntax.


I suggest that you abandon your current approach altogether.

What is it that you are actually trying to accomplish?

There is almost certainly a way to get what you want without
the potential bugs and obtuse machinations required by
using Symbolic References.

Given a couple of functions:

#########
sub Test1
{
print "Test1\n";
}

sub Test2
{
print "Test2\n";
}

#######

How can I call the subroutine that is named in a scalar variable
$func?


One way would be to look it up directly in the Symbol Table hash:

$main::{$func}->();

But don't do that.


Another way would be by using a Symbolic Reference (perldoc perlref).

no strict 'refs';
$func->();

But don't do that either.

Using symrefs is a Very Bad Idea...

Here, the scalar $func will contain either "Test1" or "Test2"


.... so use real references rather than symbolic references by using
your own hash for the dispatch table rather than using the %main::
hash for your dispatch table.


--------------------------
#!/usr/bin/perl
use warnings;
use strict;

sub Test1
{
print "Test1 got called\n";
}

sub Test2
{
print "Test2 got called\n";
}

my %dispatch = (
Test1 => \&Test1,
Test2 => \&Test2,
);

foreach my $func ( 'Test1', 'Test2' ) {
print "calling $func()...\n";
$dispatch{$func}->();
}
 
S

sln

I have a question on Perl syntax. Given a couple of functions:

#########
sub Test1
{
print "Test1\n";
}

sub Test2
{
print "Test2\n";
}

#######

How can I call the subroutine that is named in a scalar variable
$func?
Here, the scalar $func will contain either "Test1" or "Test2"

e.g. this doesn't work:

&($func)

Thanks,
Neil


Typically, uses are as a callback or dispatch table.
Each require the function address or reference to be
generically passed in and stored in another variable.
OR, knowing the KEY or INDEX where a particular handler's
function pointer or reference is stored.

In the old days for instance, packet handler adresses
in C were stored in an array of function pointers.
The packet was put together with the enum of the index into
this array imbedded into an inner layer, then sent down the pipe
where the reciever extracted the data layer containing the index,
then passed the data to the handler.

Still though, there is always a resolution to a fixed VARIABLE containing
the function address or reference. This instead of a symbolic reference.

Callbacks and handlers are a way for the caller to set a user defined function
that the callee calls at a later time in responce to some trigger. This can
be set any time but typically called sometime later.
Using methods as callbacks are a little trickier and may need wrappers.

In Perl, the caller needs to identify the handler (if many are used) to
the callee. The identifier can be an exported (if the callee is a module) constant
or a disposable key name, either of which are passed as an identifier, along with
the function reference and/or other data to the callee who either calls the function
immediatly or stores the reference into a callee provided variable, either hash or
scalar array.

At this point the callee can do basic checks like ref($val) eq 'CODE' or such as
that.

Anyway, the use of & when calling a function allows the callee to see the callers
@_ when dispatching functions and is usually used as a pass through, for example,
when called from the replacement side of a s///e regex.

Anyway, here are some examples. Perlsub should give more info. But in general,
symbolic reference is bad.

-sln

----------------------------
use warnings;
use strict;

sub Test1
{
print "@_ Test1\n";
}

sub Test2
{
print "@_ Test2\n";
}

my %funcref = (
Test1 => \&Test1,
Test2 => \&Test2,
Test3 => sub {print "@_ Test3 anonymous sub\n";},
Test4 => sub {print "@_ Test4 anonymous sub\n";},
);

@_ = ('some', 'stuff');

for my $code (sort keys %funcref)
{
print ".. $code\n";
my $fn = $funcref { $code };
$fn->();
&$fn;
$funcref{ $code }();
&{$funcref{ $code }};
$funcref{ $code }->();
print "\t---\n";
}

__END__

... Test1
Test1
some stuff Test1
Test1
some stuff Test1
Test1
---
... Test2
Test2
some stuff Test2
Test2
some stuff Test2
Test2
---
... Test3
Test3 anonymous sub
some stuff Test3 anonymous sub
Test3 anonymous sub
some stuff Test3 anonymous sub
Test3 anonymous sub
---
... Test4
Test4 anonymous sub
some stuff Test4 anonymous sub
Test4 anonymous sub
some stuff Test4 anonymous sub
Test4 anonymous sub
---
 
N

neilsolent

Thanks for the answers everyone.
Yes I understand the risks, I was mainly just interested in what the
syntax was.
 
U

Uri Guttman

n> Thanks for the answers everyone.
n> Yes I understand the risks, I was mainly just interested in what the
n> syntax was.

you don't understand the risks if you are curious to use symrefs. that
is the whole point! the safest and best way for many reasons is a
dispatch table. using symrefs means you are using a specialized hash
(the symbol table) for general purpose data structures. it is the same
thing as a dispatch table but with nasty side effects. so why use
symrefs at all! the rule is you use symrefs when you want to mung the
symbol table, not for general data.

now google for dispatch tables as there are many threads which cover it
well and also why symrefs are not a good solution.

uri
 
S

sln

In the old days for instance, packet handler adresses
in C were stored in an array of function pointers.
^^^^^^^^^^^^^^^^^^^^^^^^^^
As an aside, I challenge anybody to write a prototype in C
of a named array of function pointers with typed parameters, that
return a type. I can do it.

-sln
 
C

Charlton Wilbur

n> Thanks for the answers everyone. Yes I understand the risks, I
n> was mainly just interested in what the syntax was.

You have an answer, so it's not like I'll prevent you, but my usual
response to this is that this is something that is bad programming
practice, and so if you don't know how to do it, that's a sign that you
really shouldn't be doing it.

Charlton
 
N

neilsolent

you don't understand the risks if you are curious to use symrefs. that
is the whole point! the safest and best way for many reasons is a
dispatch table. using symrefs means you are using a specialized hash
(the symbol table) for general purpose data structures. it is the same
thing as a dispatch table but with nasty side effects. so why use
symrefs at all! the rule is you use symrefs when you want to mung the
symbol table, not for general data.

now google for dispatch tables as there are many threads which cover it
well and also why symrefs are not a good solution.

uri

Real men don't worry about symrefs.
 
U

Uri Guttman

LS> This begs the question that "professional" is a superset of "competent",
LS> and I would argue that it is not. I've seen far too many programmers
LS> who are "professional" (in the sense of word that they do it full time
LS> and derive their livelihood from programming) who produce code, that if
LS> handed in by a sophomore student would be rejected.

LS> So -- COMPETENT programmers worry about symrefs :)

in my high school drama class we were taught this:

there are professional acting companies who are amateur and amateur
companies who are professional. i would think tad's use of professional
is the competent meaning vs the being paid.

uri
 

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

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,710
Latest member
bernietqt

Latest Threads

Top