我们最近遇到了一个问题,即在发生一系列提交后,后端进程无法运行 . 现在,我们是优秀的小男孩和女孩,并在每次办理登机手续后都跑了 rake test
但是,由于Rails库加载中的一些奇怪现象,它只发生在我们在 生产环境 模式下直接从Mongrel运行时 .
我追踪了这个错误,这是因为一个新的Rails gem在一个方法中覆盖了一个方法,该方法打破了运行时Rails代码中的一个狭隘用法 .
无论如何,长话短说,有没有办法在运行时询问Ruby在哪里定义了一个方法?像 whereami( :foo )
那样返回 /path/to/some/file.rb line #45
的东西?在这种情况下,告诉我它是在类String中定义的将是无益的,因为它被某些库重载 .
我不能保证源代码存在于我的项目中,因此对 'def foo'
的求助并不一定会给我我需要的东西,更不用说我是否有很多__10810_ 's, sometimes I don' t知道直到运行时我可能正在使用它 .
10 回答
答案很晚:)但早期的答案并没有帮助我
我迟到了这个帖子,很惊讶没有人提到
Method#owner
.这真的很晚了,但是你可以在这里找到定义方法的地方:
http://gist.github.com/76951
如果您使用的是Ruby 1.9,则可以使用source_location
请注意,这不适用于所有内容,例如本机编译代码 . Method class也有一些简洁的函数,比如Method#owner,它返回定义方法的文件 .
编辑:另请参阅
__file__
和__line__
以及其他答案的REE注释,它们也很方便 . - wg也许
#source_location
可以帮助找到方法的来源 .例如:
返回
要么
返回
你可以做这样的事情:
foo_finder.rb:
然后确保首先加载foo_finder
(我只是搞砸了轨道,所以我不确切知道,但我想有一种方法可以像这样开始 . )
这将显示String#foo的所有重新定义 . 通过一些元编程,您可以将其概括为您想要的任何功能 . 但它确实需要在实际进行重新定义的文件之前加载 .
这可能会有所帮助,但您必须自己编写代码 . 粘贴在博客上:
http://scie.nti.st/2008/9/17/making-methods-immutable-in-ruby
从较新的similar question复制我的答案,为此问题添加新信息 .
Ruby 1.9 有一个名为source_location的方法:
这个gem被反向移植到 1.8.7 :
所以你可以请求方法:
然后询问该方法的
source_location
:这将返回一个包含文件名和行号的数组 . 例如
ActiveRecord::Base#validates
这将返回:对于类和模块,Ruby不提供内置支持,但是如果没有指定方法,那么有一个优秀的Gist构建在
source_location
之上,用于返回给定方法的文件或类的第一个文件:在行动:
在安装了TextMate的Mac上,这也会弹出指定位置的编辑器 .
实际上你可以比上面的解决方案更进一步 . 对于Ruby 1.8 Enterprise Edition,
Method
实例上有__file__
和__line__
方法:对于Ruby 1.9及更高版本,有
source_location
(感谢Jonathan!):您总是可以使用
caller()
来回溯您所在的位置 .如果你可以崩溃这个方法,你会得到一个回溯,它会告诉你确切的位置 .
不幸的是,如果你不能崩溃它,那么你无法找到它的定义 . 如果您尝试通过覆盖或覆盖它来尝试使用该方法,那么任何崩溃都将来自您的覆盖或重写方法,并且它将没有任何用处 .
崩溃方法的有用方法:
传递
nil
它禁止它 - 很多时候该方法将在一个零级别上引发ArgumentError
或永远存在的NoMethodError
.如果你对方法有内在的了解,并且你知道该方法依次调用其他方法,那么你可以覆盖另一个方法,并在其中加注 .