Подтвердить что ты не робот

Ruby Conditional-Assignment и частные методы

Из приведенного ниже кода представляется, что оператор ||= оценивается вне класса.

class Foo
  attr_reader :bar

  def baz
    self.bar ||= 'baz'
  end

  private

  attr_writer :bar
end

puts Foo.new.baz
# => in `baz': private method `bar=' called for #<Foo:0x007fd9720829a8> (NoMethodError)

Цитата из принятого ответа на Официальное расширение оператора || = оператора условного присваивания:

In other words, the expansion c = c || 3 is (excluding bugs like in pre-1.9) correct.

Переписывание метода baz как self.bar = self.bar || 'baz' не вызывает ошибки.

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

Такое поведение присутствует в Ruby версии 1.9.3, 2.0.0 и 2.1.2, что заставляет меня думать, что это не ошибка.

4b9b3361

Ответ 1

Это выглядит как bug.

UPDATE: bug был исправлен в trunk и для переноса по умолчанию на 2.1 и 2.0.

Обратите внимание, что проблема более общая, чем эта, она нарушена для всех сокращенных назначений, а не только условных сокращенных присвоений:

private def foo=(*) end
public  def foo; 0  end

self.foo =  42

self.foo += 42
# private method `foo=' called for main:Object (NoMethodError)

private :foo

self.foo += 42
# private method `foo' called for main:Object (NoMethodError)