我们最近遇到了一个问题,在一系列提交之后,一个后端进程无法运行。现在,我们都很乖,每次签入后都会运行rake测试,但是,由于Rails库加载中的一些奇怪之处,它只在我们直接从Mongrel在生产模式下运行时才会发生。
我追踪了这个bug,它是由于一个新的Rails gem覆盖了String类中的一个方法,这种方法破坏了运行时Rails代码中的一个狭窄使用。
总之,长话短说,有没有一种方法,在运行时,问Ruby在哪里定义了一个方法?类似于whereami(:foo),返回/path/to/some/file。Rb线45号?在这种情况下,告诉我它是在类String中定义的是没有帮助的,因为它被一些库重载了。
我不能保证源生活在我的项目,所以grepping 'def foo'不一定给我我需要的,更不用说,如果我有很多def foo's,有时我不知道,直到运行时,我可能会使用哪一个。
也许#source_location可以帮助查找方法的来源。
ex:
ModelName.method(:has_one).source_location
返回
[project_path/vendor/ruby/version_number/gems/activerecord-number/lib/active_record/associations.rb", line_number_of_where_method_is]
OR
ModelName.new.method(:valid?).source_location
返回
[project_path/vendor/ruby/version_number/gems/activerecord-number/lib/active_record/validations.rb", line_number_of_where_method_is]
很晚才回答:)但之前的回答对我没有帮助
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
实际上,您可以比上面的解决方案更进一步。对于Ruby 1.8企业版,Method实例中有__file__和__line__方法:
require 'rubygems'
require 'activesupport'
m = 2.days.method(:ago)
# => #<Method: Fixnum(ActiveSupport::CoreExtensions::Numeric::Time)#ago>
m.__file__
# => "/Users/james/.rvm/gems/ree-1.8.7-2010.01/gems/activesupport-2.3.8/lib/active_support/core_ext/numeric/time.rb"
m.__line__
# => 64
对于Ruby 1.9和更高版本,有source_location(谢谢Jonathan!):
require 'active_support/all'
m = 2.days.method(:ago)
# => #<Method: Fixnum(Numeric)#ago> # comes from the Numeric module
m.source_location # show file and line
# => ["/var/lib/gems/1.9.1/gems/activesupport-3.0.6/.../numeric/time.rb", 63]
也许#source_location可以帮助查找方法的来源。
ex:
ModelName.method(:has_one).source_location
返回
[project_path/vendor/ruby/version_number/gems/activerecord-number/lib/active_record/associations.rb", line_number_of_where_method_is]
OR
ModelName.new.method(:valid?).source_location
返回
[project_path/vendor/ruby/version_number/gems/activerecord-number/lib/active_record/validations.rb", line_number_of_where_method_is]