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

发布于 2024-11-03 10:43:40 字数 782 浏览 1 评论 0原文

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

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

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)

I don't want an alias_method solution. I'm looking for something like this.

UPDATE

The solution doesn't need to be any similar to the link above; it's only a suggestion. For example, I tried to do:

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

but this way I get an weird ArgumentError on Ruby 1.8.7.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦在深巷 2024-11-10 10:43:40

我认为使用您链接的 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:绑定到不同对象的单例方法”异常。

I don't think it's doable using the SuperProxy approach you linked to.

In this case, A.method(:a) is a singleton method. Singleton methods can only be bound to the object it was created with. In particular, it cannot be rebound to B.

Here's the first non-working approach I tried:

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

Second non-working approach:

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

Both generate a "TypeError: singleton method bound for a different object" exception.

不打扰别人 2024-11-10 10:43:40

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

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

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

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

When calling a method in the derived class B, with respect to instances of the derived class there is absolutely no difference between the A instance object and the B instance object. They are exactly the same object.

So when considering instance methods, there is only one single object. It's conceptually possible if slightly tricky, as you noted, to call a method defined in the parent class but with, of course, the derived class as the self instance. There is no way to distinguish between an "A" object and a "B" object, there is but a single instance and they are the "same" for A and B. But for class methods, the parallel with the rebound instance method you referred to simply does not exist.

Now, you are talking about class methods. For class methods, as you know, self is the class. Instances are meaningless. You cannot call class method A.whatever without having class A or its metaclass be self.

In other words, the reason your referenced trick works is because there is only one object, and for a derived instance it's named from the derived class. There is no way to do the opposite without creating a second instance of the underived parent class. But now that we are calling class methods they are .. well .. class methods, so there is no hope of referring to a derived class. How, exactly, could what you want even be defined?

白况 2024-11-10 10:43:40

这里唯一的解决方案是使用 Ba

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

Only solution here is to use B.a.

class B < A
  def self.b
    a #=> self: B; superclass: A
  end
end  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文