如何以编程方式确定哪个类/模块定义了正在调用的方法?
在 Ruby 中,如何以编程方式确定哪个类/模块定义了正在调用的方法?
假设在给定范围内我调用 some_method()
。在同一范围内,我想调用一个函数 find_method(:some_method)
,该函数将返回哪个类、单例类或模块定义 some_method
。
这里有一些代码来说明我的意思:
class Foo
include ...
def bar
...
some_method() # calls a method in scope, assume it exists
find_method(:some_method) # Returns where the method is defined
# e.g. => SomeClassOrModule
...
end
end
我猜我必须使用反射函数的复杂组合,从 self
开始,并使用 self.ancestors
来向上走继承树,使用 method_define?
检查某个方法是否在类或模块上定义,可能还有一些其他技巧来检查从最内层到最外层的范围(因为代码可能在例如, instance_eval
)。
我只是不知道 Ruby 元模型实现 find_method 的正确顺序和所有微妙之处,这样它的搜索既详尽又从方法分派解析的角度来看是正确的。
谢谢!
In Ruby, how can I programmatically determine which class/module defines a method being called?
Say in a given scope I invoke some_method()
. In the same scope I'd like to invoke a function find_method(:some_method)
that would return which Class, Singleton Class or Module defines some_method
.
Here's some code to illustrate what I mean:
class Foo
include ...
def bar
...
some_method() # calls a method in scope, assume it exists
find_method(:some_method) # Returns where the method is defined
# e.g. => SomeClassOrModule
...
end
end
I'm guessing I have to use a complex mixture of reflective functions, starting with self
and using self.ancestors
to walk up the inheritance tree, using method_defined?
to check if a method is defined on a Class or Module, and probably some other tricks to inspect scopes from the innermost to the outermost (since the code may run within, e.g., an instance_eval
).
I just don't know the correct order and all the subtleties of the Ruby metamodel to implement find_method
such that it's both exhaustive in its search and correct from a method dispatch resolution perspective.
thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
发现这出奇的简单。整洁的!
扩展这个答案,以展示如何实际返回所有者类:
如果您发现,请将其包装在实例方法中这是必要的,但这并没有那么糟糕,不是吗?
Found that this was surprisingly simple. Neat!
Expanding on this answer, to show how to actually return the owner class:
Wrap that in an instance method if you find it necessary, but that's not really that bad, eh?