Есть ли случаи, когда в Perl необходима строка eval? - PullRequest
12 голосов
/ 23 февраля 2010

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

Ответы [ 4 ]

6 голосов
/ 23 февраля 2010

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

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

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

  1. оценки символьных ссылок
  2. выполнить любой код от пользователя
  3. ошибки перехвата
  4. , если есть какой-либо другой способ сделать это

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

5 голосов
/ 23 февраля 2010

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

4 голосов
/ 23 февраля 2010

eval EXPR можно использовать для метапрограммирования, если вы не можете положитесь на лося или подобное рамки для создания классов на лету. Посмотрите на источник Исключение :: 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 !

0 голосов
/ 23 февраля 2010

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

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

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

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

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

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

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

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

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

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

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

...