Can't use string ("mysub") as a subroutine ref while "strict refs" in
use at testing.pl line 5
Here is the code
#!/usr/bin/perl
use strict;
my $sub = "mysub";
&$sub;
sub mysub {
print "hello this does not work while use strict is on\n";
}
How can I get this to work while still having 'use strict' on?
--
Mike Machado
mi...@innercite.com
InnerCite
Network Specialist
> Can't use string ("mysub") as a subroutine ref while "strict refs" in
> use at testing.pl line 5
>
Only hard references are allowed while using strict.
For example:
#!/usr/local/bin/perl -w
use strict;
my $sub = \&mysub;
&$sub;
sub mysub {
print "hello WILL work while use strict is on\n";
}
__END__
>my $sub = "mysub";
>&$sub;
>
>sub mysub {
> print "hello this does not work while use strict is on\n";
>}
>
>How can I get this to work while still having 'use strict' on?
Why?
You can replace it with:
my $sub = \&mysub;
&$sub;
which is a safer way of achieving this (and probably a bit faster, too).
Otherwise, try:
{
no strict "refs";
&$sub;
}
The block limits the scope of the "no strict" pragma.
Bart.
> I am trying to use a scalar as a subroutine name while I have use strict
> on and I keep getting the error:
>
> Can't use string ("mysub") as a subroutine ref while "strict refs" in
> use at testing.pl line 5
>
> Here is the code
>
>
> #!/usr/bin/perl
> use strict;
>
> my $sub = "mysub";
> &$sub;
>
> sub mysub {
>
> print "hello this does not work while use strict is on\n";
>
> }
>
>
> How can I get this to work while still having 'use strict' on?
>
Never.
You are using something called 'symbolic reference'. That is, you try to
referr to your subroutine by name (&$subroutine_name).
Well, this _is_ possible, but: symbolic references only work on global
variables (routines) in your package (script). You can't use them with
vars and routines declared with 'my'. Because symbolic references _can_
cause trouble, strict won't allow them.
Try to use a socalled 'hard reference' instead:
1. No 'symbolism' here:
sub my_function {...};
$my_func = \&my_function; # note the magic backslash.
. # note, that $func_ref still is
. # a scalar, but does *not* contain
. # your function's name, but some kind
. # of a pointer to your function.
.
.
$result = &$my_func; # here we go, strict won't complain
2. If you need to use the name of your function,
use a hash before (plus a hard reference):
sub my_function {...};
%func_refs = ('my_function' => \&my_function);
. # here you can use anything as
. # your 'symbolic' function-name
. # _but_ note the backslash again
.
.
$my_func = 'my_function';
. # $my_func is a scalar _and_ contains
. # no reference at all..
.
.
# here we go again, strict won't complain, 'symbolism' is working fine:
$result = &{$func_refs{$my_func}};
For details on references, see the perlref + perlfaq 7 pages in your
Perldocs.
hth, Hartmut
--
-----------------------------------
CREAGEN Computerkram
Hartmut Camphausen
Kirchstrasse 8
35042 Marburg
Fon: 06424/923826
Fax: 06424/923827
Emil: h.c...@creagen.de
WWW: http://www.creagen.de/
Mike Machado <mi...@innercite.com> wrote:
> I am trying to use a scalar as a subroutine name while I have use strict
> on and I keep getting the error:
>
> Can't use string ("mysub") as a subroutine ref while "strict refs" in
> use at testing.pl line 5
Well, you -can- use the string as a subroutine reference with strict
turned on. I've brought this up several times with no responses from the
elite Perl gurus. Perhaps this falls under mjd's "How to tell if
a file is a hard link?" style of question.
So the standard answers (which have already been given) are to
either turn of strict refs for the call of the symbolic function
reference or to use a hard ref. Both of which are the correct
answers. However, you may also do:
&{\&{$func_name}}('args');
even if strict is turned on.
My comments on the issue:
http://www.deja.com/=dnc/getdoc.xp?AN=432546967&fmt=text
http://www.deja.com/=dnc/getdoc.xp?AN=439096145&fmt=text
mjd's discussion on questions (worth reading):
http://www.plover.com/~mjd/perl/Questions.html
The upshot of my complaint is this:
#!/usr/bin/perl -w
use strict;
sub foo { print "foo is called\n" }
my $ref1 = &{"foo"}; # Error: String as subroutine ref
my $ref2 = \&{"foo"}; # No error
my $ref3 = &{"no_such_func"}; # Error:
my $ref4 = \&{"no_such_func"}; # No error
print "ref4 = $ref4\n"; # A CODE reference? What?
__END__
Tramm
--
o hud...@swcp.com tbh...@cs.sandia.gov O___|
/|\ http://www.swcp.com/~hudson/ H 505.266.59.96 /\ \_
<< KC5RNF @ N5YYF.NM.AMPR.ORG W 505.284.24.32 \ \/\_\
0 U \_ |
> In article <377129F1...@innercite.com>, mi...@innercite.com says...
> 2. If you need to use the name of your function,
> use a hash before (plus a hard reference):
>
> sub my_function {...};
> %func_refs = ('my_function' => \&my_function);
> . # here you can use anything as
> . # your 'symbolic' function-name
> . # _but_ note the backslash again
> .
> .
> $my_func = 'my_function';
> . # $my_func is a scalar _and_ contains
> . # no reference at all..
> .
> .
> # here we go again, strict won't complain, 'symbolism' is working fine:
> $result = &{$func_refs{$my_func}};
I'm doing something similar in my email script, where I have a global hash
that maps subject strings to their appropriate filter modules
(subroutines):
$filter_hash{"default"} = \&Default_Filter::def_Filter;
# a global hash which maps subject strings to function references
# (filters)
When calling the function using the hard reference in
this fashion (similar to what you have, only with an argument):
&$filter_hash{"default"}(@message);
I get the following error:
Can't use subscript on subroutine entry at ./Master_Filter line 90, near
"'default'}"
(Did you mean $ or @ instead of &?)
I got around it by using the following hack:
$code = $filter_hash{"default"};
# code gets a reference to the default filter
&$code(@message);
# de-reference the function and apply it to the msg
Is there a better way to do this? Also, for debugging purposes, I output
the contents of the the hash, which is presumably a pointer to a function:
print "I will use this function: $filter_hash{'default'}\n";
output: "I will use this function: CODE(0x154df4)"
Is there a way to have it output the name of the function instead of the
address of it? In other words, can I get back the function name from the
address?
Thanks for any insight.
Regards,
Shane
=========================================================================
Shane M. Fisher
CS Major, Western Washington University
E-Mail: fis...@acm.wwu.edu, smfi...@gte.net
Web: http://www.acm.wwu.edu/fishers
=========================================================================
Shane Fisher (fis...@lister.acm.wwu.edu) wrote:
: I'm doing something similar in my email script, where I have a global hash
: that maps subject strings to their appropriate filter modules
: (subroutines):
:
: $filter_hash{"default"} = \&Default_Filter::def_Filter;
: # a global hash which maps subject strings to function references
: # (filters)
:
: When calling the function using the hard reference in
: this fashion (similar to what you have, only with an argument):
:
: &$filter_hash{"default"}(@message);
You've got your precedences wrong. Dereferencing has a higher precedence
that subscripting, so your code is actually trying to treat $filter_hash
as a subroutine reference, dereference it, and then try to subscript the
result. Two solutions:
1) &{$filter_hash{default}}(@message);
Here the curlies force $filter_hash{default} to be treated as a block
which evaluates to the actual reference. Note that you don't need quotes
around a hash key if the key meets the rules for a Perl identifier.
2) $filter_hash{default}->(@message);
IMHO, this looks better.
: Is there a better way to do this? Also, for debugging purposes, I output
: the contents of the the hash, which is presumably a pointer to a function:
:
: print "I will use this function: $filter_hash{'default'}\n";
: output: "I will use this function: CODE(0x154df4)"
:
: Is there a way to have it output the name of the function instead of the
: address of it? In other words, can I get back the function name from the
: address?
No. If you want to be able to access the function name, you'll have to
use a multi-dimensional hash and store a copy of the function name yourself.
Hi,
> > # here we go again, strict won't complain, 'symbolism' is working fine:
> > $result = &{$func_refs{$my_func}};
>
> I'm doing something similar in my email script...
Yes, something _similar_ ;-)
Note the curly brackets...
...and referr to Eric's posting. If you use the (really better readable)
'->'-dereferencing mechanism, you'll _have_ to put the round, args-
enclosing brackets '(..)' after the '->', even if you don't pass any args
to your function:
$result = $func_refs{$my_func}->();
That works ok.
mfg, Hartmut
>
> You've got your precedences wrong. Dereferencing has a higher precedence
> that subscripting, so your code is actually trying to treat $filter_hash
> as a subroutine reference, dereference it, and then try to subscript the
> result. Two solutions:
>
> 1) &{$filter_hash{default}}(@message);
>
> Here the curlies force $filter_hash{default} to be treated as a block
> which evaluates to the actual reference. Note that you don't need quotes
> around a hash key if the key meets the rules for a Perl identifier.
>
> 2) $filter_hash{default}->(@message);
>
> IMHO, this looks better.
Thanks, number two works great!
> The upshot of my complaint is this:
>
> #!/usr/bin/perl -w
> use strict;
> sub foo { print "foo is called\n" }
>
> my $ref1 = &{"foo"}; # Error: String as subroutine ref
> my $ref2 = \&{"foo"}; # No error
>
> my $ref3 = &{"no_such_func"}; # Error:
> my $ref4 = \&{"no_such_func"}; # No error
> print "ref4 = $ref4\n"; # A CODE reference? What?
> __END__
Could this just be a case of autovivification? I mean, if you
just took a variable and treated it as an array ref, for example,
Perl wouldn't complain until you actually tried to do something with
the referenced value (trying to print an element of the array if
you hadn't populated it, say). If I add a line
&{$ref4};
after code similar to yours above, I get the print statement's output,
plus a run-time error message:
ref4 claims to be CODE(0x2007ee34)
Undefined subroutine &main::no_such_func called at -e line 9.
I guess Perl has no way of knowing you're not going to do something
like
do 'file_defining_no_such_func_et_al.pl';
_after_ the ref assignment but _before_ the sub call I have above,
which would make the whole deal perfectly legal. Making the
ref assignment _itself_ (i.e., populating the scalar with a ref
to a (currently) undefined sub) illegal would prevent you from
performing this (perhaps contrived but at least syntactically valid
as far as I can see) sequence.
Perl's philosophy of "innocent until proven guilty" has suited
a miscreant like me quite well. :)
Darrin
Mike Machado wrote:
> I am trying to use a scalar as a subroutine name while I have use strict
> on and I keep getting the error:
>
> Can't use string ("mysub") as a subroutine ref while "strict refs" in
> use at testing.pl line 5
>
I think the trick you are looking for is...
use strict;
my $sub = "mysub";
eval($sub);
sub mysub {
print "eval is great for dynamic functionality";
}
Shane Mayer