private不会阻塞模块中的函数调用(Ruby)

Mat*_*zny 2 ruby private

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)

阻止第一次调用,但我想知道什么是私有模块的一些用例.

Gab*_*ira 5

开始理解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)