我们最近遇到了一个问题,在一系列提交之后,一个后端进程无法运行。现在,我们都很乖,每次签入后都会运行rake测试,但是,由于Rails库加载中的一些奇怪之处,它只在我们直接从Mongrel在生产模式下运行时才会发生。

我追踪了这个bug,它是由于一个新的Rails gem覆盖了String类中的一个方法,这种方法破坏了运行时Rails代码中的一个狭窄使用。

总之,长话短说,有没有一种方法,在运行时,问Ruby在哪里定义了一个方法?类似于whereami(:foo),返回/path/to/some/file。Rb线45号?在这种情况下,告诉我它是在类String中定义的是没有帮助的,因为它被一些库重载了。

我不能保证源生活在我的项目,所以grepping 'def foo'不一定给我我需要的,更不用说,如果我有很多def foo's,有时我不知道,直到运行时,我可能会使用哪一个。


当前回答

你总是可以通过使用caller()得到你所在位置的回溯。

其他回答

这可能会有帮助,但您必须自己编写代码。贴自博客:

Ruby提供了method_added() 调用的回调函数 方法中添加或重新定义 类。它是Module类的一部分, 每个类都是一个模块。有 也调用了两个相关的回调 method_removed()和 method_undefined()。

http://scie.nti.st/2008/9/17/making-methods-immutable-in-ruby

这真的很晚了,但下面是如何找到定义方法的地方:

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

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类也有一些简洁的函数,比如Method#owner,它返回定义方法的文件。

编辑:也请参阅另一个答案中的__file__和__line__以及REE的注释,它们也很方便。——工作组

很晚才回答:)但之前的回答对我没有帮助

set_trace_func proc{ |event, file, line, id, binding, classname|
  printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname
}
# call your method
set_trace_func nil

我来晚了,很惊讶没有人提到Method#owner。

class A; def hello; puts "hello"; end end
class B < A; end
b = B.new
b.method(:hello).owner
=> A

如果你能让这个方法崩溃,你会得到一个回溯,它会告诉你它的确切位置。

不幸的是,如果不能使它崩溃,那么就无法找到它的定义位置。如果您试图通过重写或重写方法来操纵该方法,那么任何崩溃都将来自您所重写或重写的方法,并且它将没有任何用处。

崩溃方法的有用方法:

在禁止的地方传递nil——很多时候该方法会在nil类上引发ArgumentError或始终存在的NoMethodError。 如果您有方法的内部知识,并且知道该方法反过来调用其他方法,那么您可以重写其他方法,并在其中引发。