Mor*_*ori 5 ruby metaprogramming subclass super ruby-2.3
在运行时的方法中,有没有办法知道是否已super在子类中调用该方法?例如
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!"
Run Code Online (Sandbox Code Playgroud)
我怎么写via_super?,或者,如果有必要的话via_super?(:bar)?
我的其他答案、@mudasobwa和@sawa 的答案加上递归支持的最终组合:
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
Run Code Online (Sandbox Code Playgroud)
唯一不起作用的情况(AFAIK)是如果您在基类中有间接递归,但我不知道如何通过解析代码来处理它。
| 归档时间: |
|
| 查看次数: |
144 次 |
| 最近记录: |