Ruby - 调用超类中的另一个类方法
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为使用您链接的 SuperProxy 方法是不可能的。
在本例中,
A.method(:a)
是一个单例方法。单例方法只能绑定到创建它的对象。特别是,它不能反弹到B
。这是我尝试的第一个非工作方法:
第二种非工作方法:
两者都会生成“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 toB
.Here's the first non-working approach I tried:
Second non-working approach:
Both generate a "TypeError: singleton method bound for a different object" exception.
当调用派生类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?
这里唯一的解决方案是使用
Ba
。Only solution here is to use
B.a
.