当前的Ruby方法是通过super调用的吗? [英] Is the current Ruby method called via super?
本文介绍了当前的Ruby方法是通过super调用的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
在运行时的方法中,是否有办法知道该方法是否已通过子类中的super
调用?例如
Within a method at runtime, is there a way to know if that method has been called via super
in a subclass? E.g.
module SuperDetector
def via_super?
# what goes here?
end
end
class Foo
include SuperDetector
def bar
via_super? ? 'super!' : 'nothing special'
end
end
class Fu < Foo
def bar
super
end
end
Foo.new.bar # => "nothing special"
Fu.new.bar # => "super!"
我怎么写via_super?
,或者如果需要的话,写via_super?(:bar)
?
How could I write via_super?
, or, if necessary, via_super?(:bar)
?
推荐答案
我的其他人, @ mudasobwa's 和 @ sawa's 答案以及递归支持:
The ultimate mix between my other, @mudasobwa's and @sawa's answers plus recursion support:
module SuperDetector
def self.included(clazz)
unless clazz.instance_methods.include?(:via_super?)
clazz.send(:define_method, :via_super?) do
first_caller_location = caller_locations.first
calling_method = first_caller_location.base_label
same_origin = ->(other_location) do
first_caller_location.lineno == other_location.lineno and
first_caller_location.absolute_path == other_location.absolute_path
end
location_changed = false
same_name_stack = caller_locations.take_while do |location|
should_take = location.base_label == calling_method and !location_changed
location_changed = !same_origin.call(location)
should_take
end
self.kind_of?(clazz) and !same_origin.call(same_name_stack.last)
end
end
end
end
唯一不起作用的情况(AFAIK)是您在基类中具有间接递归,但是我不知道如何通过解析代码来处理它.
The only case that wont work (AFAIK) is if you have indirect recursion in the base class, but I don't have ideas how to handle it with anything short of parsing the code.
这篇关于当前的Ruby方法是通过super调用的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文