Почему (a_method ||: other) возвращает: other только при назначении переменной с именем a_method? - PullRequest
5 голосов
/ 13 января 2011

Учитывая следующий метод:

def some_method
  :value
end

Следующие утверждения работают так, как я ожидал:

some_method || :other
# => :value

x = some_method || :other
# => :value

Но поведение следующего утверждения озадачивает меня:

some_method = some_method || :other
# => :other

Создает локальную переменную с именем some_method, как и ожидалось, и последующие вызовы some_method возвращают значение этой локальной переменной. Но почему он присваивает :other, а не :value?

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

Я тестировал это в Ruby 1.8.7 и Ruby 1.9.2 с одинаковыми результатами.

Ура!

Пол

Ответы [ 2 ]

5 голосов
/ 13 января 2011

Были похожие вопросы, но не совсем то же самое. Ответ Йорга здесь, похоже, дошло до того, что я цитирую соответствующую часть:

На этом этапе определено foo, даже если строка никогда не будет выполнена,Тот факт, что строка никогда не выполняется, совершенно не имеет значения, потому что интерпретатор в любом случае не имеет к этому никакого отношения: локальные переменные определяются синтаксическим анализатором, и синтаксический анализатор, очевидно, видит эту строку.

Итак,в вашем случае, независимо от того, что метод с таким именем уже существует, анализатор видит присваивание some_method и автоматически «помечает» идентификатор как локальную переменную.Таким образом, когда интерпретатор начинает оценивать правую часть присваивания, он уже считает some_method локальной переменной, а не методом.Его значение не назначено (nil по умолчанию), поэтому результат || будет :other.

4 голосов
/ 13 января 2011

Простой ответ: ваше последнее утверждение совпадает с

some_var = some_var || :other

, потому что когда у вас есть локальная переменная в области действия с тем же именем, что и у метода, интерпретатор дает приоритет локальной переменной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...