Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Sub ref from string without eval

by lackita (Acolyte)
on Apr 02, 2012 at 14:38 UTC ( #963022=perlquestion: print w/ replies, xml ) Need Help??
lackita has asked for the wisdom of the Perl Monks concerning the following question:

How would I convert "Foo" to \&Foo without using eval?

Comment on Sub ref from string without eval
Select or Download Code
Re: Sub ref from string without eval
by moritz (Cardinal) on Apr 02, 2012 at 14:50 UTC
Re: Sub ref from string without eval
by kennethk (Monsignor) on Apr 02, 2012 at 14:51 UTC
    I suspect this is an XY Problem, but you can do this using Symbolic references. This will not work with strict refs in place (you do use strict, right?), so your code might look like
    my $x = 'Foo'; my $sub_ref = do { no strict 'refs'; \&{$x}; };
    so your code might look like
    my $x = 'Foo'; my $sub_ref = \&{$x};
    Update: It appears my $sub_ref = \&{'Foo'}; passes strict when &{'Foo'}; does not. Huh?

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      \&{$x} works perfectly fine with strict refs. It is only implicit usage of strings as references that is prohibted by strict refs. If you go to the length of writing \&{ ... }, perl assumes a symbolic reference is indeed what you want.
      use strict; use warnings; use 5.010; sub Foo { 'in sub Foo' } my $x = 'Foo'; my $sub_ref = \&{$x}; say $sub_ref->(); __END__ in sub Foo

        It is only implicit usage of strings as references that is prohibted by strict refs.

        Nope.

        $ perl -e'use strict; my $x = "foo"; \${ $x }' Can't use string ("foo") as a SCALAR ref while "strict refs" in use at + -e line 1. $ perl -e'use strict; \${ "foo" }' Can't use string ("foo") as a SCALAR ref while "strict refs" in use at + -e line 1.

        \&{ ... } is clearly an exception.

      To quote strict:

      There is one exception to this rule:

      $bar = \&{'foo'}; &$bar;

      is allowed so that goto &$AUTOLOAD would not break under stricture.

Re: Sub ref from string without eval
by stevieb (Hermit) on Apr 02, 2012 at 15:00 UTC
    #!/usr/bin/perl use strict; use warnings; # install within block to temporarily # turn off strict refs { no strict 'refs'; *{'Foo'} = sub { print "Hello, world!\n"; }; } my $foo = \&Foo();

    EDIT: Forgot about strict 'refs'

Re: Sub ref from string without eval
by stevieb (Hermit) on Apr 02, 2012 at 15:27 UTC

    ...and just to be safe, I'll throw up this writeup by Mark Jason Dominus

    Yes, I have had it handed out lovingly to me years ago, and aside from the odd edge case (creating accessors from a config file where Moose wasn't available), I still don't have any reason to do it :)

      and aside from the odd edge case (creating accessors from a config file where Moose wasn't available)

      That is not an edge case, just another instance where you shouldn't use a variable as a variable name

Re: Sub ref from string without eval
by Khen1950fx (Canon) on Apr 02, 2012 at 15:30 UTC
    I would convert "Foo" to \&Foo without using an eval by using a closure:
    #!/usr/bin/perl -l use strictures 1; use Devel::SimpleTrace; sub Foo { use strict 'refs'; use warnings; my $x = shift(); return sub { my $y = shift(); print "$x, $y!"; } } use strict 'refs'; my $h = Foo("Hello"); my $g = Foo("Goodbye"); print &$h("Bar"); print &$g("Baz");
Re: Sub ref from string without eval
by Anonymous Monk on Apr 02, 2012 at 20:19 UTC

    If you know which package you expect your subroutine to be in you might also be able to use the functionality of UNIVERSAL::can

    use strict; use warnings; sub Foo { warn 'foo'} my $x = 'Foo'; my $sub_ref = main->can($x); $sub_ref->();
      Which is generalized even better as:

      my $sub_ref = __PACKAGE__->can($x);

      my @a=qw(random brilliant braindead); print $a[rand(@a)];

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (16)
As of 2014-08-27 16:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (244 votes), past polls