Когда 'оценка' в Ruby выровнена по ширине?

"'Оценка', как предполагается, противна?" вдохновил этот:

Главным образом все согласовывают это eval плохо, и в большинстве случаев существует более изящная/более безопасная замена.

Таким образом, я хотел спросить: если eval неправильно используется, что часто, это действительно необходимо как функция языка? Это делает более злой, чем хороший?

Лично, единственное место, я нахожу это полезным, состоит в том, чтобы интерполировать строки, обеспеченные в файле конфигурации.

Править: Намерение этого вопроса состоит в том, чтобы получить как можно больше реальных случаев, когда оценка является единственным или лучшим решением. Таким образом, не входите, "должен язык ограничивать креативность программиста" направление.

Edit2: И когда я говорю eval, конечно, я обращаюсь к evalстрока луга, не передающий рубиновый блок к instance_eval или class_eval.

26
задан Community 23 May 2017 в 10:31
поделиться

7 ответов

Единственный известный мне случай (кроме «У меня есть эта строка, и я хочу ее выполнить») - это динамическая работа с локальным и глобальные переменные. В Ruby есть методы для получения имен локальных и глобальных переменных, но отсутствуют методы для получения или установки их значений на основе этих имен. Единственный способ сделать AFAIK - использовать eval .

Любое другое использование почти наверняка неверно. Я не гуру и не могу категорически утверждать, что других нет, но во всех других случаях использования, которые я когда-либо видел, когда кто-то сказал: «Для этого вам нужен eval», я нашел решение, которого не было.

Обратите внимание, что я говорю здесь, кстати, о string eval . Ruby также имеет instance_eval , который может принимать либо строку, либо блок для выполнения в контексте получателя. Блочная форма этого метода быстрая, безопасная и очень полезная.

23
ответ дан 28 November 2019 в 06:31
поделиться

Когда это оправдано? Я бы сказал, когда нет разумной альтернативы. Мне удалось придумать одно использование, где я не могу придумать альтернативы: irb, который, если копнуть достаточно глубоко (до workspace.rb , около строки 80 в моей копии, если вам интересно ) использует eval для выполнения вашего ввода:

def evaluate(context, statements, file = __FILE__, line = __LINE__)
  eval(statements, @binding, file, line)
end

Это кажется мне довольно разумным - ситуация, когда вы конкретно не знаете, какой код вам нужно будет выполнить, до того самого момента, когда вас попросят это сделать. Что-то динамичное и интерактивное, кажется, отвечает всем требованиям.

15
ответ дан 28 November 2019 в 06:31
поделиться

There is one very important use-case for eval() which cannot (AFAIK) be achieved using anything else, and that is to find the corresponding object reference for a binding.

Say you have been passed a block but (for some reason) you need access to object context of the binding, you would do the following:

obj = eval('self', block.binding)

It is also useful to define the following:

class Proc
    def __context__
        eval('self', self.binding)
    end
end
6
ответ дан 28 November 2019 в 06:31
поделиться

eval - это инструмент, он не является ни добром, ни злом. Это оправдано, когда вы уверены, что это правильный инструмент для того, чего вы пытаетесь достичь.

3
ответ дан 28 November 2019 в 06:31
поделиться

Такой инструмент, как eval, предназначен для оценки кода во время выполнения, а не во время "компиляции". Вы знаете, что это за код при запуске Ruby? Тогда вам, вероятно, не понадобится eval. Генерирует ли ваш код код во время выполнения? тогда вам, вероятно, потребуется его оценить.

Например, методы / функции, необходимые в рекурсивном приличном парсере, зависят от анализируемого языка. Если ваше приложение создает такой синтаксический анализатор на лету, возможно, имеет смысл использовать eval. Вы можете написать обобщенный синтаксический анализатор, но это может оказаться не таким элегантным решением.

« Программное заполнение letrec в Scheme. Макросы или eval? » - это вопрос, который я написал об eval в Scheme, где его использование в большинстве случаев неизбежно.

2
ответ дан 28 November 2019 в 06:31
поделиться

eval существует потому, что когда он вам нужен, когда он вам действительно нужен, нет заменителей. В конце концов, с диспетчеризацией творческих методов вы можете сделать так много, и в какой-то момент вам нужно выполнить произвольный код.

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

Я бы сказал, что когда вы находите язык программирования, лишенный опасности, вы находите один, который не очень полезен.

Когда является eval оправдано? Говоря прагматично, когда вы говорите, что это так. Если это ваша программа и вы программист, вы устанавливаете параметры.

12
ответ дан 28 November 2019 в 06:31
поделиться

IMO в основном для доменных языков.

« Параметры оценки в Ruby » - это статья Джея Филдса об этом в InfoQ.

5
ответ дан 28 November 2019 в 06:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: