如何找到在运行时定义方法的位置? [英] How to find where a method is defined at runtime?

查看:124
本文介绍了如何找到在运行时定义方法的位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们最近遇到了一个问题,即在进行了一系列提交之后,后端进程无法运行.现在,我们是个不错的男孩和女孩,每次检入后都运行rake test,但是由于Rails库加载的某些奇怪情况,只有在我们以生产模式从Mongrel直接运行它时,这种情况才会发生.

We recently had a problem where, after a series of commits had occurred, a backend process failed to run. Now, we were good little boys and girls and ran rake test after every check-in but, due to some oddities in Rails' library loading, it only occurred when we ran it directly from Mongrel in production mode.

我跟踪了该错误,这是由于一个新的Rails gem覆盖了String类中的一种方法,从而打破了运行时Rails代码中的一种狭义用法.

I tracked the bug down and it was due to a new Rails gem overwriting a method in the String class in a way that broke one narrow use in the runtime Rails code.

总之,长话短说,在运行时有没有办法问Ruby在哪里定义了一个方法?像whereami( :foo )这样返回/path/to/some/file.rb line #45的东西?在这种情况下,告诉我它是在String类中定义的,将无济于事,因为它已被某些库重载.

Anyway, long story short, is there a way, at runtime, to ask Ruby where a method has been defined? Something like whereami( :foo ) that returns /path/to/some/file.rb line #45? In this case, telling me that it was defined in class String would be unhelpful, because it was overloaded by some library.

我不能保证源代码存在于我的项目中,因此对'def foo'的grepping并不一定能满足我的需求,更不用说我是否有很多 def foo我直到运行时才知道我可能正在使用哪一个.

I cannot guarantee the source lives in my project, so grepping for 'def foo' won't necessarily give me what I need, not to mention if I have many def foo's, sometimes I don't know until runtime which one I may be using.

推荐答案

这确实很晚,但是您可以通过以下方法找到方法的定义位置:

This is really late, but here's how you can find where a method is defined:

http://gist.github.com/76951

# How to find out where a method comes from.
# Learned this from Dave Thomas while teaching Advanced Ruby Studio
# Makes the case for separating method definitions into
# modules, especially when enhancing built-in classes.
module Perpetrator
  def crime
  end
end

class Fixnum
  include Perpetrator
end

p 2.method(:crime) # The "2" here is an instance of Fixnum.
#<Method: Fixnum(Perpetrator)#crime>

如果您使用的是Ruby 1.9+,则可以使用 source_location

If you're on Ruby 1.9+, you can use source_location

require 'csv'

p CSV.new('string').method(:flock)
# => #<Method: CSV#flock>

CSV.new('string').method(:flock).source_location
# => ["/path/to/ruby/1.9.2-p290/lib/ruby/1.9.1/forwardable.rb", 180]

请注意,这不适用于所有内容,例如本机编译代码. 方法类也具有一些简洁的功能,例如 Method#owner 会返回文件,其中方法已定义.

Note that this won't work on everything, like native compiled code. The Method class has some neat functions, too, like Method#owner which returns the file where the method is defined.

另请参见__file____line__以及REE注释,它们也很方便. -wg

Also see the __file__ and __line__ and notes for REE in the other answer, they're handy too. -- wg

这篇关于如何找到在运行时定义方法的位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆