为什么我可以在Ruby中使用Object#send访问私有/受保护的方法? [英] Why can I access private/protected methods using Object#send in Ruby?
问题描述
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 = 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
问题
标为测试输出"的部分是预期的结果.那么,为什么我只能通过Object#send
访问私有/受保护的方法?
The question
The section labeled "Test Output" is the expected result. So why can I access private/protected method by simply Object#send
?
在Ruby中public
/private
/protected
有什么区别?什么时候使用每个?有人可以提供private
和protected
用法的真实示例吗?
What is the difference between public
/private
/protected
in Ruby? When to use each? Can someone provide real world examples for private
and protected
usage?
推荐答案
技术上:因为send
不执行任何操作来检查方法的可见性. (这样做会做更多的工作.)
Technically: Because send
doesn't do anything to check method visibility. (It would be more work to do so.)
从哲学上讲:Ruby是一种非常宽松的语言.您已经可以打开一个类并公开您想要的任何方法.语言设计者以允许其覆盖private
通常施加的限制的方式来实现send
. Ruby 1.9最初将具有两个变体,一个是private
-尊敬的send
和一个不安全的变体,称为send!
,但是为了向后兼容,显然删除了它.
Philosophically: Ruby is a very permissive language. You can already just open up a class and make any method you want public. The language designers implemented send
in a way that allows it to override the restrictions normally imposed by private
. Ruby 1.9 was originally going to have two variants, a private
-respecting send
and an unsafe variant called send!
, but this was apparently dropped for backwards compatibility.
关于private
,protected
和public
的含义:
-
public
方法可以被任何发送者调用 -
protected
方法不能在该方法的类的实例或子类的实例之外调用. -
private
方法不能用显式接收器调用(有两个例外,例如setter方法,它们总是必须有一个显式接收器,因此可以在类中以这种方式调用)
public
methods can be called by any senderprotected
methods cannot be called outside of an instance of the method's class or an instance of a subclassprivate
methods cannot be called with an explicit receiver (with a couple of exceptions, such as setter methods, which always have to have an explicit receiver, and so can be called within the class that way)
这篇关于为什么我可以在Ruby中使用Object#send访问私有/受保护的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!