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 } };
Другие вопросы по тегам