1
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解决方案。我正在寻找这样的东西

更新

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

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

但这样我ArgumentError对 Ruby 1.8.7 感到很奇怪。

4

3 回答 3

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:为不同对象绑定的单例方法”异常。

于 2011-04-25T04:43:59.457 回答
2

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

所以在考虑实例方法时,只有一个对象。正如您所指出的,如果有点棘手,那么从概念上讲,调用父类中定义的方法是可能的,但当然,派生类作为 self 实例。没有办法区分“A”对象和“B”对象,只有一个实例,它们对于 A 和 B 是“相同的”。但是对于类方法,与反弹实例方法并行所指的根本不存在。

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

换句话说,您引用的技巧起作用的原因是因为只有一个对象,并且对于派生实例,它是从派生类命名的。如果不创建未派生父类的第二个实例,就无法反其道而行之。但是现在我们正在调用类方法,它们是..好吧..类方法,所以没有希望引用派生类。究竟如何定义你想要的东西?

于 2011-04-25T04:51:29.370 回答
1

这里唯一的解决方案是使用B.a.

class B < A
  def self.b
    a #=> self: B; superclass: A
  end
end  
于 2011-08-18T06:12:20.533 回答