Twój kod jest poprawny w ogóle, ale trzeba wyłączyć strict 'refs'
aby Perl pozwala używać zmiennej treści, co odn kodowych.
use strict;
use warnings;
sub foo { print "foo" }
sub bar { print "bar" }
my @arr = qw/foo bar/;
foreach my $sub (@arr) {
no strict 'refs';
print "Calling $sub\n";
&$sub();
}
Wyjście tutaj jest:
Calling foo
fooCalling bar
bar
Dodałem także nawias ()
po wywołaniu. W ten sposób nie przekazujemy żadnych argumentów do %$sub
. Jeśli tego nie zrobimy, zostanie użyta lista argumentów bieżącego podprogramu @_
.
Jednak prawdopodobnie nie należy tego robić. Zwłaszcza jeśli @arr
zawiera dane wejściowe użytkownika, jest to duży problem. Twój użytkownik może wstrzyknąć kod. Rozważ to:
my @arr = qw/CORE::die/;
Teraz otrzymujemy następujący wynik:
Calling CORE::die
Died at /home/code/scratch.pl line 1492.
Ups. Nie chcesz tego robić. Przykład die
nie jest zły, ale w ten sposób można łatwo wywołać kod w innym pakiecie, który nie był przeznaczony.
Prawdopodobnie lepiej jest wykonać dispatch table. Istnieje cały rozdział na temat tych w Wyższego rzędu Perl Marka Jason Dominus, który można download for free on his website.
Oznacza to po prostu, że umieścisz wszystkie subwoofery w haszu jako odwołania do kodu, a następnie wywołaj te w pętli. W ten sposób możesz kontrolować, które z nich są dozwolone.
use strict;
use warnings;
sub baz { print "baz" }
my %dispatch = (
foo => sub { print "foo" },
bar => sub { print "bar" },
baz => \&baz,
);
my @arr = qw/foo bar baz wrong_entry/;
foreach my $sub (@arr) {
die "$sub is not allowed"
unless exists $dispatch{$sub};
$dispatch{$sub}->();
}
This wyjścia:
foobarbaz
wrong_entry is not allowed at /home/code/scratch.pl line 1494.
'(\ & $ nazwa) -> (@ args)' – ikegami