What Does Private Method Really Mean?

既然已经了解了 self,现在就可以重新审视 Ruby 的 private 关键字了。私有方法服从一个简单的规则:不能明确指定一个接收者来调用一个私有方法。因此,每次调用一个私有方法时,只能调用于隐含的接收者—-self 上。

  class C
    def public_method
      self.private_method
    end

    private

    def private_method;end
  end

  C.new.public_method
  #=> NoMethodError: private method 'private_method' called [...]

在这段代码中,如果去掉 self 关键字,它就可以正常运行。

  • 私有方法是由两条规则一起控制的:第一条,如果调用方法的接收者不是你自己,则必须明确指明一个接收者;第二条,私有方法只能被隐含接收者调用。把这两条规则糅和在一起,你会发现 只能在自身中调用一个私有方法。可以把这个糅和后的规则称为“私有规则”。

当有疑问时,只需要参考“私有规则”,所有的事情就会豁然开朗。如果对象 x 和对象 y 都是同一个类的对象,则 x 能调用 y 的私有方法么?不能,因为不管属于哪个类,始终需要明确指明接收者来调用另一个对象的方法。能调用你超类中的私有方法么?可以,因为你无需明确指明接收者调用继承来的方法。

Object Model Wrap-up

  • 对象由一组实例变量和一个类的引用组成。

  • 对象的方法存在于对象所属的类中,从类的角度看,它们叫做实例方法。

  • 类本身是 Class 类的对象,类的名字不过是一个常量而已。

  • Class 类是 Moudle 的子类,一个模块基本上是由一组方法组成的包,类除了具有模块的特性之外,还可以被实例化(通过 new 方法),及被组织为层次结构(通过 superclass 方法)。

  • 常量像文件系统一样,是按照树形结构组织的。其中模块和类的名字扮演目录的角色,其他普通的常量则扮演文件的角色。

  • 每个类都有一个祖先链,这个链从自己所属的类开始,向上直到 BasicObject 类结束。

  • 当调用一个方法时,Ruby 首先向右一步来到接收者所属的类,然后一直向上查找祖先链,直到找到该方法,或者到达链的顶端为止。

  • 每当类包含一个模块时,该模块会被插入到祖先链中,位置在该类的正上方。

  • 当调用一个方法时,接收者会扮演 self 的角色。

  • 当定义一个模块或者类时,该模块扮演 self 的角色。

  • 实例变量永远都被认定为 self 的实例变量。

  • 任何没有明确指定接收者的方法调用,都当成是调用 self 的方法。