Re: Sub ref from string without eval
by moritz (Cardinal) on Apr 02, 2012 at 14:50 UTC
|
my $subref = \&{"Foo"};
| [reply] [d/l] |
Re: Sub ref from string without eval
by kennethk (Abbot) on Apr 02, 2012 at 14:51 UTC
|
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.
| [reply] [d/l] [select] |
|
\&{$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
| [reply] [d/l] [select] |
|
$ 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.
| [reply] [d/l] [select] |
|
To quote strict:
There is one exception to this rule:
$bar = \&{'foo'};
&$bar;
is allowed so that goto &$AUTOLOAD would not break under stricture.
| [reply] [d/l] [select] |
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 :)
| [reply] |
|
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
| [reply] |
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");
| [reply] [d/l] [select] |
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->();
| [reply] [d/l] |
|
Which is generalized even better as:
my $sub_ref = __PACKAGE__->can($x);
my @a=qw(random brilliant braindead); print $a[rand(@a)];
| [reply] [d/l] |
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'
| [reply] [d/l] |