Почему присвоение обрабатывается по-разному в этой условной строке? - PullRequest
2 голосов
/ 12 августа 2011

Я прочитал несколько вещей, включая это и это , но я думаю, что приведенный ниже пример отличается от того, о чем они говорят.Один человек на самом деле приводит аналогичный пример в дискуссии, но он игнорируется.

Итак, запустите в irb (игнорируйте предупреждения о назначении в условном выражении):

(puts x) if (x = 0) # NameError: undefined local variable or method `x'...
x                   # => 0
(puts x) if (x = 0) # "0", => nil

, но во второй раз ошибки нет.

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

Для ясности, приведенное выше условное выражение должно быть эквивалентно (верно?)

if newvar=0
  puts newvar
end

, что не вызывает ошибку.


Обновление: естьбыло еще больше сообщений на эту тему, так как этот вопрос был задан.Например,
http://seejohncode.com/2012/07/31/ruby-gotcha-single-line-conditionals/.

Ответы [ 4 ]

1 голос
/ 12 августа 2011

Я думаю, что разница в этом случае заключается в том, существует ли переменная, когда она анализирует строку. В случае:

if x=0
  puts x
end

переменная x определена до того, как она проанализирует строку, которая использует x.

Другими словами, сообщение об ошибке является ошибкой времени разбора, а не ошибкой времени выполнения.

1 голос
/ 12 августа 2011

Как ни странно, это прекрасно работает в Рубиниусе:

Welcome to IRB. You are using rubinius 1.2.4dev (1.8.7 7ae451a1 yyyy-mm-dd JI)
>> (puts x) if (x = 0) #=> nil
0

Я склонен сказать, что это странная ошибка синтаксического анализа в МРТ.

0 голосов
/ 12 августа 2011

Сначала убедитесь, что вы имеете в виду x=0 в условном предложении.

Во-вторых, puts x if x = 0 не эквивалентно:

if x = 0
  puts x
end

В вашем случае x еще не объявлен для puts x, поэтому он не может его увидеть.

0 голосов
/ 12 августа 2011

Я думаю, что в этом вы назначаете 0 для х.

(puts x) if (x = 0)

Я думаю, что это должно быть

(puts x) if (x == 0)
...