【问题标题】:Difference between self.class and class << selfself.class 和 class << self 之间的区别
【发布时间】:2014-01-31 02:30:18
【问题描述】:

试图了解 private 和 protected 在用于类方法时是如何工作的,我从some other question 获得了这段代码:

class Bang
    def instance_bang
      self.class.class_bang
    end

    protected
    def self.class_bang
      puts "bang"
    end
end

从 Bang 实例调用 instance_bang 可以按预期工作,但是当我采用使用 class 的方法时,我无法理解以下代码中有什么不同.

class Bang
  def instance_bang
    self.class.class_bang
  end

  class << self
    protected 
    def class_bang
      puts "bang"
    end
  end
end

对我来说,两段代码似乎相同,但第二段代码失败,NoMethodError 声称 class_bang 受到保护。

【问题讨论】:

  • 在实例方法instance_bang 中self.class.class_bang 开头的self. 可能会让您感到困惑。它不是必需的,因为如果没有给出接收者,则假定为self。如果您不确定,请使用class.class_bang 尝试。在 IRB 或 PRY 中。
  • 刚刚尝试使用 2.1.0 并收到语法错误gist.github.com/fgarcia/8382526#file-gistfile1-txt-L3-L5
  • @CarySwoveland 你需要照原样写self.class.class_bang。如果您使用class.class_bang,MRI 会将其视为class 关键字。所以你会得到错误。
  • 我的立场是正确的。我必须在早上再看一次,用新鲜的眼睛。
  • 这很有趣。 @Arup,我不否认需要 self. 来告诉 Ruby 你指的是方法,而不是关键字,但是考虑到 class 链接到 class_bang,为什么 Ruby 不够聪明知道这一点? self. 是必需的,例如,当后面跟着一个 setter 方法时,将它与局部变量区分开来,但我不明白这里的需要,虽然这可能不是深入研究的地方。

标签: ruby class


【解决方案1】:

在第二段代码中,protected 用于指定 Bang 类的方法的可见性。但是'def self.class_bang'在Bang的单例类上定义了一个方法,所以受保护的键将不适用于该方法。

在第一块代码中,你打开了 Bang 的单例类,因此 protected 用于指定 Bang 的单例类的方法的可见性,这意味着 protected 将适用于 class_bang 方法。这就是你得到错误的原因。

欲了解更多信息,请阅读:http://blog.jayfields.com/2006/11/ruby-protected-class-methods.html

【讨论】:

  • 所以这就是原因!但是,这是否意味着在 Bang#instance_bang 中调用 Bang.class_bang 的唯一方法是使用 send 方法?
  • 是的,因为您没有在其类体内或其子类体内调用受保护的方法。 Bang 是其单例类的实例,而不是其单例类的子类。
猜你喜欢
  • 2011-01-02
  • 1970-01-01
  • 1970-01-01
  • 2012-01-13
  • 1970-01-01
  • 2011-11-18
  • 2018-11-02
  • 2016-04-13
  • 2016-11-05
相关资源
最近更新 更多