Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Sub ref from string without eval

by lackita (Sexton)
on Apr 02, 2012 at 14:38 UTC ( [id://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?

Replies are listed 'Best First'.
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 (Abbot) 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 (Canon) 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)];
Re: Sub ref from string without eval
by stevieb (Canon) 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'

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
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?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (3)
As of 2024-04-19 02:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found