module Test
private
def secret
puts '<>'
end
end
include Test
secret #it works
Test.secret #it fails: "private method `secret' called for Test:Module (NoMethodError)"
Run Code Online (Sandbox Code Playgroud)
私人是否有这样的设计理由?我知道我可以使用
private_class_method :secret
Run Code Online (Sandbox Code Playgroud)
阻止第一次调用,但我想知道什么是私有模块的一些用例.
开始理解Ruby中私有方法的一般方法是将其视为只能隐式调用的方法.这意味着不应该显式指定接收方法的对象:
my_private_method # Implicit call, this is OK.
self.my_private_method # Explicit call, this won't work.
Run Code Online (Sandbox Code Playgroud)
使用这种简单的方法,您可以(在某种程度上)确保私有方法不能在除以外的对象上调用self.例如:
my_private_method # Calling private method on self, this is OK.
other_object.its_private_method # Calling other object's private method, this won't work.
Run Code Online (Sandbox Code Playgroud)
现在,当你有一个定义私有方法的模块时,你首先需要将它包含在某个地方才能使用该方法.您在示例中所做的是将模块包含在最顶层.当你这样做时,Ruby包含了Object类中的模块.这意味着您的secret方法现在是所有Ruby对象的私有方法,并且由于所有Ruby对象都具有私有secret方法,因此您可以从程序中的任何位置隐式调用它:
secret #=> "<>"
class MyClass
secret
end #=> "<>"
Run Code Online (Sandbox Code Playgroud)
为了给你一个想法,你的secret方法将表现得非常类似于puts方法(也是一种Object私有方法).您无法puts在对象上显式调用,但可以在程序中的任何位置使用它.这是一个你可能希望有一个模块中的私有方法的原因.
另一个原因可能是只实现包含模块或类的方法,例如:
module M
private
def my_private_method
"This is private."
end
end
class C
include M
def my_public_method
"<#{my_private_method}>"
end
end
c = C.new
c.my_public_method #=> "<This is private.>"
c.my_private_method #=> This won't work.
Run Code Online (Sandbox Code Playgroud)