class Example
private
def example_test
puts 'Hello'
end
end
e = Example.new
e.example_test
这当然不会起作用,因为我们指定了Example(e
)的显式接收方示例,而这违反了“私有规则”。
但我不明白,为什么不能在鲁比中这样做:
class Foo
def public_m
self.private_m # <=
end
private
def private_m
puts 'Hello'
end
end
Foo.new.public_m
public_m
方法定义中的当前对象(即self
)是Foo的示例。那么为什么不允许这样做呢?为了解决这个问题,我必须将self.private_m
更改为private_m
。但是为什么这会不同呢?self
不就是public_m
里面的Foo的一个示例吗?那么谁是private_m
裸字调用的接收者呢?那不就是self
吗--实际上你忽略了什么,因为Ruby将为您执行此操作(将在self上调用private_m)?
我希望我没有混淆它太多,我仍然新鲜的Ruby。
编辑:谢谢你所有的答案。把它们放在一起,我终于能够(终于)摸索出显而易见的东西(对于从未见过Ruby这样的东西的人来说,就不那么明显了):self
本身可以是显式和隐式的接收器,这就有区别了,所以有两个规则,如果你想调用一个私有方法:self
必须是隐式接收器,并且self必须是当前类的示例(在这种情况下为Example
-并且只有在self位于示例方法定义内时,在此方法执行期间才会发生)。如果我说错了,请更正。
class Example
# self as an explicit receiver (will throw an error)
def explicit
self.some_private_method
end
# self as an implicit receiver (will be ok)
def implicit
some_private_method
end
private
def some_private_method; end
end
Example.new.implicit
消息给任何人谁可以找到这个问题在谷歌步道:这可能会有帮助-http://weblog.jamisbuck.org/2007/2/23/method-visibility-in-ruby
8条答案
按热度按时间krugob8w1#
这里是它的简称和全称。在Ruby中,private的意思是一个方法不能被显式接收者调用,例如some_instance. private_method(value)。因此,尽管隐式接收者是self,但在示例中,您显式地使用了self,因此私有方法是不可访问的。
这样想一下,你希望能够使用一个你已经赋给类示例的变量来调用一个私有方法吗?不。Self是一个变量,所以它必须遵循同样的规则。然而,当你只是在示例中调用方法时,它会像预期的那样工作,因为你没有显式地声明接收器。
Ruby就是这样,你实际上可以使用instance_eval调用私有方法:
希望你说得更清楚一点。
我猜你知道这会有用
gojuced72#
Ruby中
private
的 * 定义 * 是“只能在没有显式接收器的情况下调用”,这就是为什么你只能在没有显式接收器的情况下调用私有方法,没有其他解释。请注意,这条规则实际上有一个例外:由于局部变量和方法调用之间的不明确性,以下内容 * 总是 * 被解析为对局部变量的赋值:
那么,如果你想调用一个名为
foo=
的编写器,你应该怎么做呢?嗯,你必须添加一个显式的接收器,因为如果没有接收器,Ruby就不知道你想调用方法foo=
,而不是赋值给本地变量foo
:但是如果你想调用一个名为
foo=
的private
编写器,你该怎么做呢?你 * 不能 * 写self.foo =
,因为foo=
是private
,因此不能用显式接收器调用。(仅在本例中),您实际上可以使用self
的显式接收器来调用private
编写器。7kqas0il3#
这很奇怪,但是Ruby的可见性修饰符的很多地方都很奇怪。即使
self
是隐式接收器,实际上拼写出来在Ruby运行时看来也是显式的。当它说私有方法不能用显式接收器调用时,这就是它的意思,即使self
也算数。eit6fx6z4#
IIRC,私有方法 * 只 * 允许隐式接收方(当然,总是self)。
11dmarpk5#
抱歉,我的回答太唐突了。我不明白你的问题。
我这样修改了你的代码:
下面是示例方法的调用:
下面是调用类的方法:
kyks70gy6#
对用户门解决方案增加了一些增强。调用私有方法到类方法或示例方法是非常可能的。这里是代码片段。但不推荐。
类方法
示例方法
vuktfyat7#
没有确切回答Question,但可以通过这种方式调用私有方法
hts6caw38#
以防现在有人搞砸了,从Ruby 2.7开始,调用一个带有字面意义self作为接收方的私有方法是允许的。
我们也可以通过在2.6.9和3.1版本上运行原始的ruby代码片段来验证这一点。
现在,如果我们尝试在2.6.9版本中运行相同的脚本,我们会看到引发了异常。