Perl sub сделан из строки
Я пытаюсь использовать подпрограмму в Perl, который содержится в строке.
В настоящее время у меня есть что-то вроде
$sub = "sub{ my $in = shift; if($in =~ /bla.*wam/){return 1;}}";
Я пытаюсь использовать это, делая
$sub->("test");
или же
&{$sub}->("test");
оба приведенных выше примера просто выплевывают всю функцию, как если бы это было имя подпрограммы, которую она не смогла найти. Это выглядит так:
Undefined subroutine [function then printed here]
Что я тут не так делаю?
3 ответа
Допустим, что скаляр $sub
содержал строку "foobar"
, Если вы тогда говорите $sub->()
, то вы пытаетесь вызвать подпрограмму с именем foobar
, Если эта подпрограмма не существует, вы получите ошибку.
Вы пытаетесь вызвать подпрограмму с именем sub{ my $in = shift; if($in =~ /bla.*wam/){return 1;}}
, которое является совершенно нелепым названием для sub и, очевидно, не существует в вашей программе. (И на самом деле, так как это в двойных кавычках, $in
вероятно, что-то интерполируется без вашего осознания.)
Так что, во-первых, не делай этого.
Если вы хотите анонимную подпрограмму, сделайте так:
my $sub = sub { my $in = shift; if($in =~ /bla.*wam/) { return 1; } };
Затем выполните это так: $sub->("test");
Если вам действительно нужно выполнить код в строке, то вы можете использовать eval
,
my $sub = eval 'sub{ my $in = shift; if($in =~ /bla.*wam/) { return 1; } }';
Это оценит код в строке и вернет результат, который является дополнительной ссылкой. Будьте очень осторожны, откуда берутся эти строки. Кто бы ни делал их, может заставить вашу программу делать то, что они хотят.
Код и строки не совпадают. Тем более, что вы как-то неправильно поняли, что ваши $sub
на самом деле Ваша строка кода - это строка в двойных кавычках. Если предположить, $in
имеет содержание bla wam
тогда вы назначили это $sub
:
"sub{ my bla wam = shift; if(bla wam =~ /bla.*wam/){return 1;}}";
Это такая синтаксическая ошибка.
Однако вы можете назначить анонимные подпрограммы непосредственно переменной:
my $sub = sub{
my $in = shift;
if ($in =~ /bla.*wam/) {
return 1;
}
};
и назовите это как в ваших примерах (хотя я предпочитаю $sub->(...)
стиль).
Удалить цитаты вокруг sub
$sub = sub { my $in = shift; if($in =~ /bla.*wam/){ return 1 } };