Ruby - 在超类中调用另一个Class方法

时间:2011-04-25 04:29:45

标签: ruby superclass class-method

class A
  def self.a
    puts "self: #{self}; superclass: #{superclass}"
  end
end

class B < A
  class << self; undef_method(:a); end  # I'm not allowed to use B.a
  def self.b
    # here I want to call A.a with B as self.
  end
end  

A.a  #=> self: A; superclass: Object
B.b  #=> self: B; superclass: A (expected)

我不想要alias_method解决方案。我正在寻找像this这样的东西。

更新

解决方案不需要与上面的链接类似;这只是一个建议。例如,我试图这样做:

class B < A
  def self.b
    instance_eval(&A.method(:a).to_proc)
  end
end

但是这样我在Ruby 1.8.7上得到了一个奇怪的ArgumentError

3 个答案:

答案 0 :(得分:2)

我不认为使用您链接的SuperProxy方法是可行的。

在这种情况下,A.method(:a)是单例方法。单例方法只能绑定到它创建的对象。特别是,它不能反弹到B

这是我尝试过的第一个非工作方法:

class B < A
  def self.b
    A.method(:a).unbind.bind(self).call
  end
end

第二种非工作方法:

class B < A
  class << self
    define_method :b, A.method(:a)
  end
end

两者都生成“TypeError:绑定到不同对象的单例方法”异常。

答案 1 :(得分:2)

在派生类B中调用方法时,对于派生类的实例,A实例对象和B实例对象之间绝对没有区别。 它们是完全相同的对象。

因此,在考虑实例方法时,只有一个对象。如上所述,如果稍微有点棘手的话,调用父类中定义的方法,当然,派生类作为自我实例,这在概念上是可能的。没有办法区分“A”对象和“B”对象,只有一个实例,它们是A和B的“相同”。但对于类方法,与回弹实例方法并行简称不存在。

现在,您正在谈论类方法。对于类方法,如您所知, self 是类。实例毫无意义。你不能在没有A类或其元类的情况下调用类方法A. self

换句话说,你引用的技巧起作用的原因是因为只有一个对象,而对于派生实例,它是从派生类中命名的。如果不创建未开发的父类的第二个实例,则无法做相反的事情。但是既然我们正在调用类方法,那么它们就是......类方法,因此没有希望引用派生类。究竟如何定义你想要的东西呢?

答案 2 :(得分:1)

此处仅解决方案是使用B.a

class B < A
  def self.b
    a #=> self: B; superclass: A
  end
end