Ответ 1
Так работает назначение; возвращаемое значение игнорируется, а результат выражения присваивания всегда является правым. Это фундаментальная черта грамматики Ruby. left-hand side = right-hand side
всегда будет оцениваться до right-hand side
, независимо от того, является ли левая сторона переменной (x
), методом (object.x)
, константой (x
) или любым выражением.
Источник: Языки программирования | Рубин Проект WGA по стандартизации IPA Ruby, 11.4.2.2.5, Назначения одиночных методов
Рассмотрим цепочку присвоений, x = y = 3
.
Для правильной работы результат y = 3
должен быть 3
, независимо от фактического значения, возвращаемого методом y=
. x = y = 3
предназначен для чтения как y = 3; x = 3
, а не как y = 3; x = y
, что и подразумевалось бы, если возвращаемое значение из y=
рассматривалось как результат y = 3
.
Или рассмотрим все другие назначения мест. Иногда вместо этого...
obj.x = getExpensiveThing()
if obj.x
...
... мы пишем это...
if obj.x = getExpensiveThing()
Это не может работать, если результат obj.x = ...
может быть любой произвольной вещью, но мы знаем, что он будет работать, потому что результат obj.x = y
всегда y
.
Обновление
A comment в вопросе говорится:
Интересно, я не знал об этом сценарии. Кажется, что метод = возвращает любой ввод данных...
Нет, это важное различие. Это не имеет никакого отношения к возвращаемому значению присваивания метода, и он определенно не "возвращает любой входной сигнал", он возвращает все, что вы скажете, чтобы он возвращался.
Все дело в том, что возвращаемое значение игнорируется грамматикой языка; присваивание не оценивает возвращаемое значение метода attr=
, но возвращаемое значение все еще существует, о чем свидетельствует сам вопрос: Example.new.send(:my_attr=, 5) # => 15
. Это работает, потому что это не присвоение. Вы перешагиваете ту часть языка Ruby.
Обновить снова
Чтобы быть ясным: x
и y
в моих примерах не должны интерпретироваться как буквальные переменные Ruby, они являются владельцами мест для любой действующей левой части задания. x
или y
может быть любое выражение: a
, obj.a
, CONSTANT_A
, Something::a
, @instance_a
, оно все равно. Значение присваивания всегда является правым.