Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Taking reference to function

by vinoth.ree (Monsignor)
on Apr 16, 2009 at 03:42 UTC ( [id://757832]=perlquestion: print w/replies, xml ) Need Help??

vinoth.ree has asked for the wisdom of the Perl Monks concerning the following question:

What is the different between the following code in case of taking reference to function

my $func_name = "funcname"; &$func_name();
my $funcref=\&thefunc; $funcref->();

When I execute the first one strict pragma throws error as, Can't use string ("thefunc") as a subroutine ref while "strict refs" in use at pl.pl line 26. So I get know that it uses symbolic references, not real (hard) references, so it is forbidden under the use strict 'refs' pragma. any other difference?

Vinoth,G

Replies are listed 'Best First'.
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->();
      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?

        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.

        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
      \&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"}
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.

      can returns a code ref so you don't need to turn off strictures, just:

      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
      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.
      Spiel auf Hündinnen.
        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.
        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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://757832]
Approved by ELISHEVA
Front-paged by targetsmart
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (8)
As of 2024-04-19 08:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found