pez*_*ser 2 ruby visibility access-specifier
w = Widget.new # Create a Widget
w.send :utility_method # Invoke private method!
w.instance_eval { utility_method } # Another way to invoke it
w.instance_eval { @x } # Read instance variable of w
Run Code Online (Sandbox Code Playgroud)
查看上面与Widget类(下面)相关的示例,send和instance_eval方法违反了私有和受保护可见性提供的所有保护.如果是这样,为什么要在Ruby中使用私有和受保护的访问权限,因为无法保证您的定义能够得到尊重?
class Widget
def x # Accessor method for @x
@x
end
protected :x # Make it protected
def utility_method # Define a method
nil
end
private :utility_method # And make it private
end
Run Code Online (Sandbox Code Playgroud)
Mar*_*llo 12
红宝石相信赋予你做你想做的事的力量.它只是不容易无意中射击你的脚 - 如果你想颠覆私人声明,你必须使用语法,明确你这样做.请注意,最终决定代码应该或不应该做的人是使用库的人,而不是编写它的人.
我无法评论,因为低代表:/.
重新定义发送是没有用的,因为发送仅仅是为了共同的名字__send__(这就是下划线,下划线,"发送",下划线,下划线),这实际上是实现信息发送的方法.不建议重新定义任何__method__.另外,另一个人也可以重新打开该类并恢复定义:
class Widget
def send(method, *args, &block)
super
end
#and so on
end
Run Code Online (Sandbox Code Playgroud)
在Ruby 1.9中,行为略有不同:#send实际上是为了尊重可见性,而__send__则没有.
Ruby中的private有更多的声明性目的:声明为private的方法是一个实现细节而不是API细节.您不得意外地从外部发送消息.但是,如果他们认为合适,任何人仍然可以强行规避这种限制 - 在他们自己的帐户上.
| 归档时间: |
|
| 查看次数: |
1333 次 |
| 最近记录: |