【问题标题】:Calling inherited class method from instance method in Ruby从Ruby中的实例方法调用继承的类方法
【发布时间】:2015-10-26 05:20:50
【问题描述】:

我有以下 Ruby 代码:

class B
  class << self
    protected
    def prot
      puts "victory"
    end
  end
end
class C < B
  def self.met
    C.prot
  end
end

C.met

它试图证明受保护的类方法在 Ruby 中是继承的。问题是,如果我将met方法转换为这样的实例方法:

class B
  class << self
    protected
    def prot
      puts "victory"
    end
  end
end
class C < B
  def met
    C.prot
  end
end

c = C.new
c.met

这行不通。也许它与类和实例方法范围有关?

【问题讨论】:

  • 我收到错误:protected method 'protegido' called for C:Class - 这表明继承确实有效……只是保护也有效。
  • @Rodrigo 你明白了吗

标签: ruby scope class-method instance-method


【解决方案1】:

不行,因为C的实例不是kind_of?(B.singleton_class)。

在 ruby​​ 中,可以在对象的上下文中调用受保护的方法,该对象是定义该方法的类 kind_of?,具有显式接收器,也是定义该方法的类 kind_of?。

您在B 的单例类上定义了一个受保护的方法,因此该方法只能在kind_of?(B.singleton_class) 的对象中调用。 C类继承了B,所以C的单例类继承了B的单例类,所以C就是kind_of? B.singleton_class。因此,在您的第一种情况下,它可以工作。但是很明显,C.new 不是kind_of? B.singleton_class,所以它不会起作用。

【讨论】:

    【解决方案2】:

    对于受保护的方法,我们可以从属于同一类的任何对象的范围内调用它们。在您的代码 sn-p 中,根据类的范围,方法查找链会在该方法继承到超类时拾取该方法。这意味着,您在其 Singleton 类中定义了一个方法,这意味着我们可以使用该类的对象来调用它。所以我们可以通过A和B的对象来调用它,因为B对象继承自A。

    总之,您可以在类的公共方法中调用受保护的方法。 请参考以下网址以更好地理解

    http://nithinbekal.com/posts/ruby-protected-methods/

    accessing protected methods in Ruby

    【讨论】:

      【解决方案3】:

      我认为这与将 .protegido 方法声明为元类(或单例类)的一部分而不是 B 类本身的一部分的区别有关。

      在这里阅读:Metaprogramming in Ruby: It's All About the Self

      【讨论】:

        猜你喜欢
        • 2020-07-13
        • 2011-02-01
        • 2010-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-23
        • 2021-06-17
        • 2012-05-28
        相关资源
        最近更新 更多