53. Функция EVAL в Perl 6

Для выполнения кода, сохраненного в строке, в Perl 6 есть функция EVAL. Именно так, большими буквами, чтобы не было похоже на Perl 5. В работе функции тоже есть отличия от старой eval.

Рассмотрим несколько вариантов. Важно понимать, что любой переданный функции код рассматривается как строка. Поэтому при наличии того, что может быть выполнено или интерполировано, оно будет выполнено или проинтерполировано (однако, если об этом явно попросить).

Простейший пример:

EVAL('say 123');

Программа ожидаемо печатает 123.

Пример чуть посложнее:

my $var = 42;
EVAL('say $var'); # 42

Эта программа напечатает 42. Вас не должно сбить с толку, что здесь стоят одинарные кавычки. Действительно, они не интерполируют переменную до передачи строки в функцию, но уже там вся строка будет обработана как программа на Perl 6, при этом переменные из внешнего кода будут видны.

Если поменять кавычки на двойные, то результат, на первый взгляд, не изменится, однако не все так просто:

my $var = 42;
EVAL("say $var");

Эта программа не работает:

===SORRY!=== Error while compiling eval3.pl
EVAL is a very dangerous function!!! (use the MONKEY-SEE-NO-EVAL pragma to override this error,
but only if you're VERY sure your data contains no injection attacks)
at eval3.pl:2
------> EVAL("say $var")⏏;

Нужно добавить специальную инструкцию. Либо так:

use MONKEY-SEE-NO-EVAL;

my $var = 42;
EVAL("say $var");

Либо так:

use MONKEY;

my $var = 42;
EVAL("say $var");

Теперь программа, которая будет выполнена внутри EVAL, полностью эквивалентна такой программе:

EVAL('say 42');

Исполнение блоков кода по умолчанию тоже не разрешено. То есть, следующая программа тоже потребует явного упоминания MONKEY:

use MONKEY;

EVAL("say {1 + 2 + 3}"); # 6

Обратите внимание, что EVAL не следует применять вместо try.

One thought on “53. Функция EVAL в Perl 6”

  1. 1) Я не очень понял, чем отличается EVAL с двойными кавычками от одинарных.
    2) В REPL «say $var».EVAL работает, а EVAL(«say $var») — нет. Почему?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Retype the CAPTCHA code from the image
Change the CAPTCHA codeSpeak the CAPTCHA code