Дело не столько в том, что сами методы являются особыми, но в большей степени связано с тем, как Ruby обрабатывает назначения (например, foo = bar
). Сначала оценивается правая часть, затем оценивается левая часть и предпринимается соответствующее действие. Если левая часть является атрибутом объекта, то вызывается соответствующий метод установки.
Итак, в вашем примере:
Dummy.new.foo = 1 { |x| x }
Первый ruby пытается вычислить 1 { |x| x }
, что и вызывает синтаксическую ошибку.
Dummy.new.foo=something
на самом деле не означает «вызов метода с именем foo=
», но на самом деле означает что-то более похожее на «evalualate something
», а затем определяет, что такое `Dummy.new.foo
, и выглядит ли он как атрибут объекта , добавьте =
к имени и вызовите этот метод ". Вот почему Dummy.new.foo=
и Dummy.new.foo =
работают одинаково.
Вы можете вызывать эти методы, используя send
, и можете передать блок следующим образом:
Dummy.new.send "foo=", 2 do
puts "HI"
end
Это потому, что с помощью send
вы можете явно назвать метод, который хотите вызвать.
Конечно, конечный результат заключается в том, что методы, оканчивающиеся на =
, по-видимому, имеют какое-то "особое" поведение, о котором вам нужно знать, но может быть полезно понять, что на самом деле происходит.