Подтвердить что ты не робот

Существуют ли какие-либо варианты использования, в которых требуется строка eval в Perl?

Можете ли вы представить примеры, когда использование eval EXPR действительно необходимо? Я спрашиваю, потому что его вообще обескураживают.

4b9b3361

Ответ 1

String eval - единственный способ:

  • выполнить новый код в определенном пакете времени выполнения
  • добавить перегрузку в пакет во время выполнения (по крайней мере, в соответствии с перегрузкой .pm)
  • выполнить произвольные строки Perl
  • скомпилировать макрокоманды

Строка eval не должна использоваться для:

  • оценить символические ссылки
  • выполнить любой код от пользователя
  • ошибки ловушки
  • если есть другой способ сделать это

eval также может использоваться для создания специальных коммуникационных протоколов между различными системами или разными языками, которые также имеют eval (при условии, что все безопасно, конечно. JSON можно рассматривать как более безопасное, но ограниченное подмножество этого метода)

Ответ 2

String eval - единственный способ сделать новый код из строк. Это редко необходимо, но есть несколько допустимых вариантов использования, например, при преобразовании шаблонов в исполняемый код. Кроме этого, для него очень мало действительных применений. eval "require $module_name" - хорошо известная идиома, но использование, например, Module::Load - лучшая идея, чем IMO.

Ответ 3

eval EXPR может использоваться для метапрограммирования, если вы не можете полагайтесь на Moose или аналогичный рамки для создания классов "на лету". Изучите источник Exception::Class чтобы увидеть полный ужас этой техники.

Приложение: (@friedo)
Одна функция, которая eval обеспечивает обработку символов таблицы это способность использовать SUPER и работать так, как ожидалось:

package Foo;
sub msg { return 'Foo' }

package MyCodeGenerator;

use strict;
use warnings;

eval <<'EOPERL'; # '' -> no variable interpolation
  package FooBar;
  @FooBar::ISA = qw/Foo/;
  sub msg {
    my $self = shift;
    return $self->SUPER::msg() . 'Bar'; # calls &Foo::msg
  }
EOPERL

Пока это (надеюсь) умрет во время выполнения или настроит вас на часовая отладочная сессия:

package BROKEN_Generator;

@FooBar::ISA = qw/Foo/;
*{'FooBar::msg'} = sub {
  my $self = shift;
  return $self->SUPER::msg() . 'Bar'; # tries to call &BROKEN_Generator::msg
}

Легко в моем Топ-5 вещей, которые я ненавижу в Perl!

Ответ 4

Несколько лет назад я написал статический генератор веб-сайтов, который использовал Perl (< - интересно, что моя проверка орфографии предлагает "Peril" в качестве замены для этого) в качестве языка сценариев. Это позволило пользователю вводить информацию о разных уровнях иерархии - первая на рынке была для кладбища, где у вас были клиенты (платящие клиенты), которые владели мемориалами (для умершего, очевидно).

У него был графический интерфейс, в который вы вводили такие переменные, как (дрожайте от моих графических навыков здесь):

+------------+----------------------------+
| ClientName | Pax Diablo                 |
+------------+----------------------------+
| Address    | 666 Hades St, Washinton DC |
+------------+----------------------------+

и переменные изображения.

Кроме того, для каждого рынка (например, вышеупомянутого кладбища) существовал контрольный script, который в основном запускал и обрабатывал каждую запись на нескольких уровнях иерархии для генерации статического содержимого. До этого программа превратила все эти переменные в такие вещи, как:

$Var{"ClientName"} = "Pax Diablo";

(Я думаю, что синтаксис прав, я не делал какой-либо Perl-разработки на некоторое время). Конечным результатом стал полный веб-сайт с большим количеством клиентов, множество мемориалов, поисковых страниц и приятный маленький денежный источник, в то время как он продолжался (я был унесен с рынка директорами похоронных бюро, предоставляя то же самое, что и "бесплатный" сервис внутри их обычные пакеты).

Но все это было в основном написано в минимальном Perl, которое делало только две вещи:

  • превратил переменные в операторы присваивания Perl; и
  • управлял специфическим для рынка кодом Perl.

Оба выполнения операторов присваивания и специфический для рынка код Perl выполнялись с помощью eval.

Так что это не так бесполезно, как вы думаете. Это был дешевый способ внедрения скриптов в приложение.