Ruby中的私有和受保护方法

时间:2011-11-29 22:40:58

标签: ruby methods access-specifier

以下代码有效:

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会导致问题?

注意:self.method_bprivate更改为protected时有效。

注意:如果将上述方法更改为类方法,则从method_a调用self.method_b不会抛出NoMethodError

2 个答案:

答案 0 :(得分:4)

这就是private方法在Ruby中的工作方式。它们不能使用显式接收器调用(除非它是一个setter方法;见下文)

在Pickaxe的 Access Control 部分阅读更多内容。

使用=调用名称以self.method_name = ... 结尾的私有方法,因为这是区分它们与设置局部变量所必需的:

class Foo
  def try
    set_foo(1)            # Invokes private method
    self.set_foo(2)       # ERROR: private method `set_foo' called for ...
    self.send(:set_foo,3) # Invokes private method

    bar = 1               # Sets local variable
    self.bar = 2          # Invokes private method
    self.send(:bar=,3)    # Invokes private method
  end

  private
    def set_foo(v)
      @foo = v
    end
    def bar=(v)
      @bar = v
    end
end

Foo.new.bar = 42          # ERROR: private method `bar=' called for ...

答案 1 :(得分:3)

这就是Ruby的工作方式:当您提供显式对象引用时,会引发NoMethodError以显示代码是破坏意图。你可以做一个self.send,它会起作用。

如果没有显式引用,Ruby不会进行相同的可见性检查;有关详细信息,请参阅this和/或this

Nutshell是使用显式接收器无法调用私有方法,即使它是self