Link to home
Start Free TrialLog in
Avatar of Buzzy Bee
Buzzy BeeFlag for United States of America

asked on

"Use Strict"

I need to do this:

my $f_name = "SomeFunctionName";
my $myvar = &$f_name($param);

This works, except when I put "use strict" at the top of my script.  How can I get "use strict" to like this?

webslider
ASKER CERTIFIED SOLUTION
Avatar of b2pi
b2pi
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of thoellri
thoellri

$ perldoc strict
.
     strict refs
           This generates a runtime error if you use symbolic
           references (see the perlref manpage).
 
               use strict 'refs';
               $ref = \$foo;
               print $$ref;        # ok
               $ref = "foo";
               print $$ref;        # runtime error; normally ok

The only way I know of to get around this problem would be:

use strict;
my $f_name = "SomeFunctionName";
{
  no strict 'refs';
  my $myvar = &$f_name($param);
}

Hope this helps
  Tobias
Avatar of Buzzy Bee

ASKER

Can you verify your syntax please?

my($f_ptr) = \&SomeFunctionName;
    -OR-
my $fname="somefunctionname";
my($f_ptr) = \$fname;


my($myvar) = &$f_prtr($param);
   -OR-
my($myvar) = &$f_ptr($param);
f_ptr is a reference to a subroutine
myvar take the result of an invocation of that subroutine.

    my($f_ptr) = \&SomeFunctionName;
    my($myvar) = &$f_prtr($param);

If you prefer, you can use

    my($myvar) = &{$f_prtr}($param);

which may be somewhat clearer.
   
b2pi: I think webslider wants you to comment on your typo :-)

      f_prtr vs. f_ptr

Ah, well, the vagaries of cut and paste.
This isn't going to work:

      my($f_ptr) = \&SomeFunctionName;

The whole point of doing this is to be able to pass a string representing the function name into a subroutine and calling the function that was requested.  Sure, I could use this if I had a CASE to handle every option but there are too many....so, use this as a bigger picture (keep in mind the following subroutine has much more going on than whats below):

sub CallThisFunction (
   my $function_name = shift;
   my $param = shift;

   my $answer = &$function_name($param);
   return $answer;
}

Thanks for your help so far!
sub CallThisFunction {
  my($function_reference) = shift;
  my($param) = shift;

# Actually, my($function_reference, $param) = @_;
# is more efficient than the above, as well as easier to maintain

  my($answer) = &{$function_reference}($param);
  return $answer;
}

Sorry, I forgot to add that you then call

$answer = CallThisFunction(\&SomeFunction, $param);

rather than

$answer = CallThisFunction("SomeFunctionName", $param);


The above suggestion works great...however there is one more sticky point....
Further in my function that I described before...I need to do this:

sub CallThisFunction (
         my $function_name = shift;
         my $another_function_name = $function_name."2";
         my $param = shift;

         my $answer = &$function_name($param);  
       #*****NEW STUFF***
         if (defined $answer) {
               $answer = &$another_function_name($param);
         }
         return $answer;  
 }

So as you can see, making the first function call is fine as described before, but generating the second function name then calling it is a problem...

Is the only way around this to add another parameter and pass the 2nd function the same as the first?  I'm really hoping not to have to do this.

webslider
Yes, you need to andd another parameter, _but_ .....

Frankly, I'd probably recode the indirect functions so that they take a parameter to indicate whether they should act like fx 1 or 2

i.e. if you had had:

sub Fx1 {
  my($val) = @_;
   return 24.3 * $val;
}

sub Fx2 {
  my($val) = @_;
   return 48.6 * $val;
}

then I'd change that to:

sub Fx {
  my($parm, $val) = @_;
  if (!defined($parm) or !$parm) {
          return $val*24.3;
  } else {
         return $val * 48.6;
 }
}

Further, if, as it appears, your two functions are sequential, then combine them into one, and have the one return the correct response (rather than relying upon the caller to call them in the right order in the right conditions.

Avatar of ozo

Actually, I have no control over rewriting the functions so that they are called with one function.  I'm just using functions that are prewritten.

Thanks for all the great help!
OK, if that's the case, and your two functions that you might want to call are fx and fx2,

then write another function like:

sub AllFx {
   my($switch, $param) = @_;
  if (defined($switch) && $switch) {
    return &fx($param);
  } else {
    return &fx2($param);
  }
}