Как module_eval / class_eval / instance_eval считает номера строк
Я нашел, что line_number передан class_eval
, module_eval
а также instance_eval
не совпадает с номерами строк, сообщенными ошибкой. Это поведение не объясняется документом ruby, который говорит: (используйте instance_eval
В качестве примера)
необязательные второй и третий параметры предоставляют имя файла и номер начальной строки, которые используются при сообщении об ошибках компиляции.
Все эти три метода class_eval
, module_eval
а также instance_eval
принимает два дополнительных параметра для указания имени файла, а параметры lineno устанавливают текст для сообщений об ошибках.
этот вопрос имеет практическую демонстрацию такого поведения.
Тем не менее, я нашел, что вычисление номеров строк более сложное, чем объяснение. Вот демо
class Thing
def add_method
a = %{
non_exist
}
instance_eval(a, 'dummy', 12)
end
end
# error will raise to 15 instead of 12 which is specified
puts Thing.new.add_method
Код выше доказывает, что line_no
парам перешел к instance_eval
это не номера строк, сообщенные ошибкой, а относятся только к line_no
,
Я задаюсь вопросом о точном поведении этих параметров?
1 ответ
Как говорится в вашем фрагменте документации, lineno
указывает номер начальной строки псевдофайла. Строка, которую вы получили, содержит три строки, где вторая строка содержит non_exist
(%{}
сохраняет разрывы строк).
Когда я выполняю ваш код, я получаю сообщение об ошибке в строке 14, а не 15, которое вы получаете. Первоначально я ожидал получить 13, но кажется, что синтаксический анализатор ruby только "заметит" ошибку на следующей строке, возможно, ищет аргументы метода или что-то еще, что имеет смысл non_exists
(Я не совсем уверен в этом). Если я вставлю еще одну пустую строку (которая не содержит отступа) после non_exists
Я получаю ожидаемое 13.
Любые строки, вставленные после %{
но прежде non_exists
увеличит номер строки в ошибке на единицу, как и следовало ожидать.