Re: Taking reference to function
by tilly (Archbishop) on Apr 16, 2009 at 05:43 UTC
|
Other than the huge difference of strict complaining, the differences are almost non-existent. But not totally so, as the following code sample shows:
sub foo {print "world,\n"}
my $func_name = "foo";
my $func_ref = \&foo;
# Replace foo
*foo = sub {print "Hello "};
&$func_name();
$func_ref->();
| [reply] [d/l] |
|
This behavior confuses me. EG:
my $string = "Hello.";
my $string_ref = \$string;
$string = "Bacon!";
print $$string_ref;
The above prints "Bacon!", as my intuition expects. Why does the coderef point to the old block? | [reply] [d/l] |
|
Because the symbol foo and the coderef are different things. *foo = ... assigns a new coderef to the symbol foo. It doesn't redefine the coderef for the original sub foo, which is kind of like a constant.
\&foo takes the address of a constant, not a variable. So it is analogous to \"Hello World" rather than \$some_var_holding_a_string. You can't reassign it any more than you can reassign the address of the string literal "Hello World".
Well, almost so. Sub "literals" are more complex than a string. Redefine a string and you get a different string. Redefine a sub and you get a different association between sub name and body. So if you *really*, *really* were set on redefining sub foo itself, you could, but (a) you have to nudge Perl into compiling code at runtime and (b) you will get a warning about redefining things that are not supposed to be redefined:
use strict;
use warnings;
sub sayHello { print "Hello, world!\n"; }
sayHello();
eval q{sub sayHello { print "Bonjour, le monde!\n"; }};
sayHello();
which outputs
Hello, world!
Subroutine sayHello redefined at (eval 1) line 1.
Bonjour, le monde!
Best, beth
Update: added some explanation about difference between sub and string literals. | [reply] [d/l] [select] |
|
Why does the coderef point to the old block?
That's not a code reference, it's a scalar reference. $string_ref is a reference to the scalar, $string. Doing a print $$string_ref; will print out whatever's *presently* in $string.
Update: Oops ... looking at Freezy's post in the context of the entire thread, I think I might've missed the point somewhat in my reply.
Cheers, Rob
| [reply] [d/l] |
|
\&thefunc is a good option..
It reduces memory consumption in symbol table
Using symbolicreferences confuses the programmer..
normally ppl will think $$variable = dereferenicing a scalar variable..if it is unavoidable then use
${"$variable"}
| [reply] |
Re: Taking reference to function
by targetsmart (Curate) on Apr 16, 2009 at 04:01 UTC
|
Both have proper uses, generally it is good to use \&thefunc
but I will use 'funcname', when have a function template configured to be executed, where it can be easily changed, by adding a new function to the module and just adding a name to the configuration. In which case in the main program, i read the configuration and just check whether that function exists using 'can', and execute it (if 'use strict' is in action, i will use 'no strict "refs"' inside that particular block so it won't throw error).
moreover the using 'funcname', does an additional lookup in the symbol table I reckon.
Vivek
-- In accordance with the prarabdha of each, the One whose function it is to ordain makes each to act. What will not happen will never happen, whatever effort one may put forth. And what will happen will not fail to happen, however much one may seek to prevent it. This is certain. The part of wisdom therefore is to stay quiet.
| [reply] |
|
use strict;
use warnings;
my $funcName = 'doit';
if (my $cando = main->can ($funcName)) {
$cando-> ();
}
sub doit {
print "I done it\n";
}
Prints:
I done it
True laziness is hard work
| [reply] [d/l] [select] |
|
Telling someone to turn off strict refs is NOT a good idea, unless right after the functions action they turn it back on. Besides why would you want to turn something off when you can get around the error.
| [reply] |
|
If you turn off strict refs inside of a block, it is automatically on right after the block. I personally find it clearer to do this than to use a complex syntax the maintenance programmer may not know to fool strict.pm into not complaining.
| [reply] |
A reply falls below the community's threshold of quality. You may see it by logging in.
|
Re: Taking reference to function
by ikegami (Patriarch) on Apr 17, 2009 at 18:14 UTC
|
| [reply] |