Частные и защищенные методы в Ruby
Следующий код работает:
class MyClass
def method_a
method_b
end
private
def method_b
puts "Hello!"
end
end
m = MyClass.new
m.method_a
Изменение вызова метода method_b на self.method_b
Однако не работает:
def method_a
self.method_b
end
Я получаю NoMethodError
, У меня сложилось впечатление, что self
просто разрешает экземпляр класса, когда внутри метода экземпляра. Почему self.method_b
вызвать проблемы?
Замечания: self.method_b
работает когда private
изменено на protected
,
Примечание: если вышеприведенные методы изменены на методы класса, то вызов self.method_b
из method_a не выбрасывает NoMethodError
,
2 ответа
Вот как private
методы работают в Ruby. Они не могут быть вызваны с явным получателем (если это не метод установки; см. Ниже).
Подробнее читайте в разделе " Контроль доступа от кирки".
Частные методы, имена которых заканчиваются на =
может быть вызван с помощью self.method_name = ...
поскольку это необходимо, чтобы отличить их от установки локальной переменной:
class Foo
def try
set_foo(1) # Invokes private method
self.set_foo(2) # ERROR: private method `set_foo' called for ...
self.send(:set_foo,3) # Invokes private method
bar = 1 # Sets local variable
self.bar = 2 # Invokes private method
self.send(:bar=,3) # Invokes private method
end
private
def set_foo(v)
@foo = v
end
def bar=(v)
@bar = v
end
end
Foo.new.bar = 42 # ERROR: private method `bar=' called for ...
Вот как работает Ruby: когда вы предоставляете явную ссылку на объект, NoMethodError
поднимается, чтобы показать, что код нарушает намерение. Вы могли бы сделать self.send
и это будет работать.
Без явной ссылки Ruby не выполняет ту же проверку видимости; посмотрите это и / или это для более подробной информации.
В двух словах: частные методы нельзя вызывать с явным получателем, даже если self
,