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
会导致问题?
注意:当 private
更改为 时,
self.method_b
可以工作受保护。
注意:如果将上述方法更改为类方法,则从 method_a 调用 self.method_b 不会抛出 NoMethodError 。
The following code works:
class MyClass
def method_a
method_b
end
private
def method_b
puts "Hello!"
end
end
m = MyClass.new
m.method_a
Changing the call to method_b to self.method_b
however does not work:
def method_a
self.method_b
end
I get a NoMethodError
. I'm under the impression that self
just resolves to the instance of the class when inside an instance method. Why does self.method_b
cause problems?
Note: self.method_b
works when private
is changed to protected
.
Note: if the above methods are changed to class methods then calling self.method_b
from method_a doesn't throw the NoMethodError
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这就是 Ruby 中
私有
方法的工作原理。不能使用显式接收器来调用它们(除非它是 setter 方法;见下文)。请阅读有关 Pickaxe 的访问控制部分了解更多信息。
名称以
=
结尾的私有方法可以使用self.method_name = ...
来调用,因为这是区分它们与设置局部变数:This is how
private
methods work in Ruby. They cannot be called with an explicit receiver (unless it is a setter method; see below).Read more in the section on Access Control from the Pickaxe.
Private methods whose names end with an
=
may be invoked usingself.method_name = ...
as this is necessary to differentiate them from setting a local variable:这就是 Ruby 的工作原理:当您提供显式对象引用时,会引发
NoMethodError
以表明代码违反了意图。你可以做一个self.send
并且它会起作用。如果没有显式引用,Ruby 就不会执行相同的可见性检查;请参阅此和/或此 了解更多详细信息。
简而言之,私有方法不能通过显式接收者调用,即使它是
self
。That's just how Ruby works: when you provide an explicit object reference,
NoMethodError
is raised to show the code is breaking intent. You could do aself.send
and it would work.Without the explicit reference, Ruby doesn't do the same visibility check; see this and/or this for a bit more detail.
Nutshell is that private methods can't be called with an explicit receiver, even if it's
self
.