calling subroutine , name derived from variable

  • Thread starter Madhu Ramachandran
  • Start date
M

Madhu Ramachandran

all:

I want to call subroutine, but the name of the subroutine itself is in a
variable. I was able to do this. However, i also want to pass arguments ..
not able to do this.
eg: if $sub has the subroutine name, and $arg has the arg to the subroutine.
How can i call this from my perl main program? i tried eval() and it worked
if i dont have any arguments.

#!/usr/local/bin/perl

$method="aSub";
$aa="\"bla\"";
$mm = "$method" . "($aa)";
print ("mm = $mm\n");
$ret = eval($mm);
print ("ret = $ret\n");
$ret=eval($method);
print ("ret = $ret\n");

sub aSub()
{
my ($arg1) = @_;
print ("inside aSub, arg1=$arg1\n");
return 1;
}
##### Output ######
mm = aSub("bla")
ret =
inside aSub, arg1=
ret = 1
##################

My perl version: This is perl, v5.6.0 built for sun4-solaris

any pointers?

Thanks in advance.

Madhu
 
M

Matt Garrish

Madhu Ramachandran said:
all:

I want to call subroutine, but the name of the subroutine itself is in a
variable. I was able to do this. However, i also want to pass arguments ..
not able to do this.

You're looking for symbolic references, but it's not good practice to use
them. For example:

$subRef = 'this_sub';
$arg1 = 'first argument';
$arg2 = 'second argument';

&{$subRef}($arg1, $arg2);

sub this_sub {
print "$_[0] : $_[1]\n";
}


It's better practice to use a hash as you won't break the strictures pragma
that way, which should make your code easier to maintain:

my %subRefs = ( this_sub => \&this_sub );

my $subRef = 'this_sub';

my $arg1 = 'first argument';
my $arg2 = 'second argument';

$subRefs{$subRef}($arg1, $arg2);

sub this_sub {
print "$_[0] : $_[1]\n";
}

Matt
 
G

Gunnar Hjalmarsson

Madhu said:
I want to call subroutine, but the name of the subroutine itself is in a
variable. I was able to do this. However, i also want to pass arguments ..

my $method = 'aSub';
my $aa = 'bla';
my $subref = \&$method;
my $ret = $subref->($aa);
print "ret = $ret\n";

sub aSub {
my ($arg1) = @_;
print "inside aSub, arg1=$arg1\n";
return 1;
}
 
R

robic0

Madhu Ramachandran said:
all:

I want to call subroutine, but the name of the subroutine itself is in a
variable. I was able to do this. However, i also want to pass arguments ..
not able to do this.

You're looking for symbolic references, but it's not good practice to use
them. For example:

$subRef = 'this_sub';
$arg1 = 'first argument';
$arg2 = 'second argument';

&{$subRef}($arg1, $arg2);

sub this_sub {
print "$_[0] : $_[1]\n";
}


It's better practice to use a hash as you won't break the strictures pragma
that way, which should make your code easier to maintain:

my %subRefs = ( this_sub => \&this_sub );

my $subRef = 'this_sub';

my $arg1 = 'first argument';
my $arg2 = 'second argument';

$subRefs{$subRef}($arg1, $arg2);

sub this_sub {
print "$_[0] : $_[1]\n";
}

Matt

This is bizzar, why would you use a hash of references to subs to call a subroutine?
Any use for that at all? Somebody gonna pass you the name of a subroutine in a packet?

The only "logical" use for an array of subroutines (or function pointers) is the "index",
into it, which means the "name" of the handler is hidden.

-robic0-
actual subroutine reference can be called.
 
G

Gunnar Hjalmarsson

Gunnar said:
my $method = 'aSub';
my $aa = 'bla';
my $subref = \&$method;
my $ret = $subref->($aa);
print "ret = $ret\n";

sub aSub {
my ($arg1) = @_;
print "inside aSub, arg1=$arg1\n";
return 1;
}

The above solution 'works', but I'd better admit that it's actually a
symref, even if it passes strict. Matt's solution was criticized by that
robic0 character, which proves that Matt provided a better answer.

Please disregard my code above.
 
J

Jürgen Exner

robic0 said:
This is bizzar, why would you use a hash of references to subs to
call a subroutine? Any use for that at all?

Oh yes, very common scenario in jump tables.

Like in (pseudo-code)
if ($op eq "add) then return $left + $right;
if ($op eq "minus") then return $left - $right;
if ($op eq "div") then return $left / $right;
...
return "Unknown op $op";

This can be written much better as

if (exists($op, %optable)) {
$optable->$op ($left, $right);
} else {
throw_error "Unknown op $op";
}

jue
 
R

robic0

Oh yes, very common scenario in jump tables.

Like in (pseudo-code)
if ($op eq "add) then return $left + $right;
if ($op eq "minus") then return $left - $right;
if ($op eq "div") then return $left / $right;
...
return "Unknown op $op";

This can be written much better as

if (exists($op, %optable)) {
$optable->$op ($left, $right);
} else {
throw_error "Unknown op $op";
}

jue

Whats a "jump" table? Whats pesuedo-code?
$i = 0
$i = 1-$i
How far does extrapolation go (down)?
Is there logic I'm unaware of?
Can I be fooled?
Do I have time for un-paid thought?
Have I done almose everything?
Can a resume save me?
-robic0-
 
T

Tad McClellan

Madhu Ramachandran said:
I want to call subroutine, but the name of the subroutine itself is in a
variable.


That is called a "symbolic reference".

Use a real reference instead:

perldoc perlreftut

perldoc perlref


sub aSub()
^^
^^

Why did you put that there?

Do you know what it does?

Is what it does what you want to have done?

{
my ($arg1) = @_;


I think not.
 
R

robic0

That is called a "symbolic reference".
Why in hell would you use it in the context of a hash of "subroutines" ?
Get off your micro-analysis and look at it from a design point of reference.
Don't ever, ever take any class I teach...
 
R

robic0

"jump tables" are an assembly acronymn.
Do you purport to parse assembly pseudonyms?
-robic-
 
G

Gunnar Hjalmarsson

Bernard said:
You snipped the bit that answers your question. :)

Yeah, I see that now. Thanks!

Tad, would you like a lesson on applying an effective followup style? ;-)
 
E

Eric J. Roode

robic0 wrote in
Whats a "jump" table? Whats pesuedo-code?

Look, if you don't understand anything about elementary computer science,
that's fine, but you don't have to boast about it.

--
Eric
`$=`;$_=\%!;($_)=/(.)/;$==++$|;($.,$/,$,,$\,$",$;,$^,$#,$~,$*,$:,@%)=(
$!=~/(.)(.).(.)(.)(.)(.)..(.)(.)(.)..(.)......(.)/,$"),$=++;$.++;$.++;
$_++;$_++;($_,$\,$,)=($~.$"."$;$/$%[$?]$_$\$,$:$%[$?]",$"&$~,$#,);$,++
;$,++;$^|=$";`$_$\$,$/$:$;$~$*$%[$?]$.$~$*${#}$%[$?]$;$\$"$^$~$*.>&$=`
 
E

Eric J. Roode

robic0 wrote in
Why in hell would you use it in the context of a hash of "subroutines"
? Get off your micro-analysis and look at it from a design point of
reference. Don't ever, ever take any class I teach...

You.... *teach*?!?

Wow. Just... wow.

--
Eric
`$=`;$_=\%!;($_)=/(.)/;$==++$|;($.,$/,$,,$\,$",$;,$^,$#,$~,$*,$:,@%)=(
$!=~/(.)(.).(.)(.)(.)(.)..(.)(.)(.)..(.)......(.)/,$"),$=++;$.++;$.++;
$_++;$_++;($_,$\,$,)=($~.$"."$;$/$%[$?]$_$\$,$:$%[$?]",$"&$~,$#,);$,++
;$,++;$^|=$";`$_$\$,$/$:$;$~$*$%[$?]$.$~$*${#}$%[$?]$;$\$"$^$~$*.>&$=`
 
M

Matt Garrish

Gunnar Hjalmarsson said:
The above solution 'works', but I'd better admit that it's actually a
symref, even if it passes strict. Matt's solution was criticized by that
robic0 character, which proves that Matt provided a better answer.

ROTFL! I'll take the compliment... : )

Matt
 
M

Madhu Ramachandran

Thank you very much for the help.
Matt Garrish said:
Madhu Ramachandran said:
all:

I want to call subroutine, but the name of the subroutine itself is in a
variable. I was able to do this. However, i also want to pass arguments
.. not able to do this.

You're looking for symbolic references, but it's not good practice to use
them. For example:

$subRef = 'this_sub';
$arg1 = 'first argument';
$arg2 = 'second argument';

&{$subRef}($arg1, $arg2);

sub this_sub {
print "$_[0] : $_[1]\n";
}


It's better practice to use a hash as you won't break the strictures
pragma that way, which should make your code easier to maintain:

my %subRefs = ( this_sub => \&this_sub );

my $subRef = 'this_sub';

my $arg1 = 'first argument';
my $arg2 = 'second argument';

$subRefs{$subRef}($arg1, $arg2);

sub this_sub {
print "$_[0] : $_[1]\n";
}

Matt
 
A

axel

Madhu Ramachandran said:
I want to call subroutine, but the name of the subroutine itself is in a
variable. I was able to do this. However, i also want to pass arguments ..
not able to do this.
eg: if $sub has the subroutine name, and $arg has the arg to the subroutine.
How can i call this from my perl main program? i tried eval() and it worked
if i dont have any arguments.
#!/usr/local/bin/perl

$method="aSub";
$aa="\"bla\"";
$mm = "$method" . "($aa)";
print ("mm = $mm\n");
$ret = eval($mm);
print ("ret = $ret\n");
$ret=eval($method);
print ("ret = $ret\n");

sub aSub()
{
my ($arg1) = @_;
print ("inside aSub, arg1=$arg1\n");
return 1;
}

Try:

#!/usr/local/bin/perl

use strict;
use warnings;

my $method="aSub";
my $aa= 'bla';

no strict;
my $ret = eval(&$method ($aa));

use strict;
print "ret = ", $ret "\n";

sub aSub() {
my $arg1 = shift;
print "inside aSub, arg1=", $arg1, "\n");
return 1;
}
 
T

Tad McClellan

Madhu Ramachandran said:
Thank you very much for the help.


You are not fooling anyone.

If you truly were thankful, then you would follow the quoting
conventions that folks expect here (and nearly everywhere else too).



DO NOT TOP POST!

DO NOT FULL-QUOTE!

Please stop abusing us!
 

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,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top