class A
private
def foo
puts :foo
end
public
def bar
puts :bar
end
private
def zim
puts :zim
end
protected
def dib
puts :dib
end
end
a = A.new
a.foo rescue puts :fail
a.bar rescue puts :fail
a.zim rescue puts :fail
a.dib rescue puts :fail
a.gaz rescue puts :fail
fail
bar
fail
fail
fail
[:foo, :bar, :zim, :dib, :gaz].each { |m| a.send(m) rescue puts :fail }
foo
bar
zim
dib
fail
Раздел маркировал "Test Output", ожидаемый результат. Итак, почему я могу получить доступ к частному / защищенному методу просто Object#send
?
Между чем различие public
/private
/protected
в Ruby? Когда использовать каждого? Может кто-то обеспечивать примеры реального мира для private
и protected
использование?
Технически: Потому что send
ничего не делает для проверки видимости метода. (Это было бы более трудоемко.)
Философски: Ruby - очень свободный язык. Вы уже можете просто открыть класс и сделать любой метод публичным. Разработчики языка реализовали send
таким образом, что он позволяет отменить ограничения, обычно накладываемые private
. В Ruby 1.9 изначально планировалось два варианта, private
- соблюдающий send
и небезопасный вариант под названием send!
, но он, очевидно, был отменен для обратной совместимости.
Что касается того, что означают private
, protected
и public
:
public
методы могут быть вызваны любым отправителемprotected
методы не могут быть вызваны вне экземпляра класса метода или экземпляра подклассаprivate
методы не могут быть вызваны с явным получателем (за парой исключений, например, методы setter, которые всегда должны иметь явного получателя, и поэтому могут быть вызваны внутри класса таким образом)