理解公案 121

Understanding koan 121

我正在(再次)完成 Ruby 公案,我(再次)达到了 121。

我已经解决了,但是有几处我不明白。这是相关的公案代码:

def my_private_method
    "a secret"
  end
  private :my_private_method

  def test_calling_private_methods_without_receiver
    assert_equal "a secret", my_private_method
  end

  def test_calling_private_methods_with_an_explicit_receiver
    exception = assert_raise(NoMethodError) do
      self.my_private_method
    end
    assert_match /__/, exception.message
  end

事实证明,如果我将倒数第二行的双下划线替换为 my_private_method 它通过了;所以 exception.message 是非方法名称的匹配项,我猜。我也可以只删除下划线,但我认为这不是本课的重点。

我认为 self.my_private_method 抛出一个 NoMethodError 并且它被分配给异常。从另一个在线教程中,我知道不能用 self 调用私有方法,所以我认为这就是重点。

但是,my_private_method 似乎不是私有的,除非 private :my_private_method 使它成为私有的。这是怎么回事? (如果是这样,我将再次对 Ruby 对如何做事情的优柔寡断以及符号似乎可以做任何事情的能力感到失望)。

那么,我的问题是:private :my_private_method 是做什么的?

当你写:

class Foo
  def bar
    # some amazing things that bar does
  end
  private :bar
end

如果你这样写也是一样的:

class Foo

  private

  def bar
    # ...
  end
end

只是语法不同,效果相同。

符号什么都不做。它们只是数据。像弦乐。或数字。方法做某事。特别是,private 方法使方法成为私有方法。 attr_accessor 方法创建两个方法。等等。

So, again, my question is: what does private :my_private_method do?

它调用方法 private 传递 :my_private_method 作为参数。如果你查看 private 的文档,它告诉你它将名称与符号匹配的方法设为私有。

So, again, my question is: what does private :my_private_method do?

private其实只是一个常规方法,定义在ModuleModule#private.

来自 the documentation for that method(强调我的):

privateself

private(symbol, ...)self

private(string, ...)self

With no arguments, sets the default visibility for subsequently defined methods to private. With arguments, sets the named methods to have private visibility. String arguments are converted to symbols.

module Mod
  def a()  end
  def b()  end
  private
  def c()  end
  private :a
end
Mod.private_instance_methods   #=> [:a, :c]