Ответ 1
Да - когда нет другого способа выполнить задание с разумным уровнем ясности и в пределах разумного количества строк кода.
Это устраняет 99% случаев, когда eval
используется по всем языкам и контекстам.
Мне кажется, что eval()
рассматривается с тем же презрением, что и goto. И eval
, я имею в виду функцию для выполнения строки как кода, как это видно на PHP, Python, JavaScript и т.д. Есть ли когда-нибудь ситуация, когда использование eval()
является оправданным (кроме perl)? И если нет, то почему это так много языков реализует?
Да - когда нет другого способа выполнить задание с разумным уровнем ясности и в пределах разумного количества строк кода.
Это устраняет 99% случаев, когда eval
используется по всем языкам и контекстам.
eval часто является наиболее целесообразным решением в ситуациях, когда вы динамически генерируете код. Даже на языках, которые официально не поддерживают eval, например Java, они поддерживают отражение и модификацию классов во время выполнения, которые аналогичны. (См. Такие книги, как Stu Halloway Разработка компонентов для платформы Java)
Одно разумное использование - если у вас есть интерпретируемый язык, который вы создали поверх другого языка, но вы все же хотите предоставить какой-то "escape-штрих", чтобы люди могли вернуться к функциям, предоставляемым основной язык. Одним из примеров является реализация Prolog в Lisp, а затем определение предиката, который позволяет напрямую использовать функции Lisp через EVAL
.
Для быстрых хаков нет проблем, потому что это удобный быстрый выход.
В производственном коде рассматривать его в последнюю очередь - и даже тогда попробуйте что-то другое, потому что eval
трудно контролировать и, следовательно, опасно. Для чего-то нетривиального, реализуйте подъязык.
Я использовал его один раз во время pentesting сайта - мы написали небольшой php script, который расшифровывает и выполняет криптографически подписанную полезную нагрузку из невостребованных источников данных HTTP на лету. Это лучшее, что я видел eval().
(Другими словами: нет, я никогда не видел хорошего использования для eval)
Непонятная мысль: eval хорош для реализации компилятора выражения бедных людей или подобных вещей. Это также тупая, ржавая замена гигиенических макросов.
Возможно, я слишком много использую sh
и perl
, но я никогда не видел, чтобы кто-то обращался eval с презрением что goto
получает.
Итак, мой ответ: 'eval
подходит, когда вы пишете perl 5
и sh
'. Блок eval
является основным механизмом try
/catch
в perl
и его трудно записать безопасный код без него.
Написал пример прохладного учебника о том, насколько легко реализовать "калькулятор" на языке X? =)
Для отладки/тестирования идеи до ее правильного использования.
Например, вы делаете игрушечный калькулятор, и сначала хотите работать с gui, поэтому просто используйте eval
для выполнения "back-end" работы в фоновом режиме. Позже вы вернетесь в исходный код, поцарапайте eval
и напишите правильный синтаксический анализатор выражений.
При создании/тестировании сегментов кода eval является PERFECT!
Просто создайте базовую веб-страницу для лесов с текстовыми полями и кнопкой eval. Поместите код в текстовое поле, а затем нажмите кнопку eval. Это быстрее, чем переключение между текстовым редактором и браузером
Eval
edit code
press eval button
метод переключения
edit code
press save extra step
switch to browser extra step
press reload
Когда вы много тестируете и настраиваете код, незначительные дополнительные шаги могут действительно скомпенсироваться. Кроме того, вы можете забыть сохранить создание путаницы при тестировании.
Eval используется, когда вам нужно "генерировать" и выполнять код. И по сгенерированию я имею в виду включение из внешнего источника (файла, веб-сайта, "агента" ), а также создание "на лету" внутри программы.
И причина, по которой вы хотите генерировать код, помимо очевидных примеров внешних модулей и сайтов оценки, обычно заключается в динамическом описании имен объектов и свойств в коде.
Первый пример, кстати, уже происходит, когда загружается страница HTML и имеет тег script, или в атрибутах обработчика события HTML-тегов - поэтому с самого начала веб-разработчик использует EVAL, даже если браузер выполняет вызов.
Это косвенно приводит меня к этой второй причине - доступ к именам объектов. На некоторых языках, таких как java, способность к интроспекции уменьшает или устраняет необходимость использования java eval. Оказывается, поскольку объекты в Javascript полностью динамичны, доступ к ресурсу в Javascript сопоставим с интроспекцией на других языках, где вы можете получить доступ и ссылаться на имена, созданные "на лету". Кроме того, Javascript имеет функции "call" и "apply" для динамического вызова функций с их параметрами.
Наконец, связанный с выполнением кода, можно использовать eval для повышения производительности - вместо многоуровневого условного или доступа к свойствам, который определяет, какой код запускать или какой объект использовать, можно создать минимальный фрагмент кода, который может иметь для выполнения сотни тысяч раз, eval его для функции, а затем просто вызвать эту функцию. Это может работать с мультиметодами, например, после определения конкретных аргументов. Конечно, это несколько и далеко друг от друга, потому что javascript рассматривает функции как объекты первого класса.