Ruby 如何动态获取方法的源代码以及该方法位于哪个文件中
我想知道我是否可以在运行中获取一个方法的源代码,以及是否可以获取该方法所在的文件 像 使用源位置: 注意,对于内置方法,source_location返回nil。如果想查看C源代码,请玩得开心!,您必须查找正确的C文件,它们或多或少是按类组织的,并在文件末尾找到该方法的rb_define_方法Ruby 如何动态获取方法的源代码以及该方法位于哪个文件中,ruby,Ruby,我想知道我是否可以在运行中获取一个方法的源代码,以及是否可以获取该方法所在的文件 像 使用源位置: 注意,对于内置方法,source_location返回nil。如果想查看C源代码,请玩得开心!,您必须查找正确的C文件,它们或多或少是按类组织的,并在文件末尾找到该方法的rb_define_方法 在Ruby 1.8中,这种方法不存在,但您可以使用。我为此创建了用于gem的ri_ >> require 'ri_for' >> A.ri_for :foo 。。。如果使用1
在Ruby 1.8中,这种方法不存在,但您可以使用。我为此创建了用于gem的ri_
>> require 'ri_for'
>> A.ri_for :foo
。。。如果使用1.9,则输出源和位置
德国劳埃德船级社。
-r到目前为止,没有一个答案显示如何动态显示方法的源代码 如果您使用Pry制造商John Mair制作的令人敬畏的“method_source”宝石,这其实非常简单: 该方法必须用Ruby而不是C实现,并且必须从文件(而不是irb)加载 下面是一个示例,显示Rails控制台中的方法源代码和方法源代码:
$ rails console
> require 'method_source'
> I18n::Backend::Simple.instance_method(:lookup).source.display
def lookup(locale, key, scope = [], options = {})
init_translations unless initialized?
keys = I18n.normalize_keys(locale, key, scope, options[:separator])
keys.inject(translations) do |result, _key|
_key = _key.to_sym
return nil unless result.is_a?(Hash) && result.has_key?(_key)
result = result[_key]
result = resolve(locale, _key, result, options.merge(:scope => nil)) if result.is_a?(Symbol)
result
end
end
=> nil
另见:
我必须实现一个类似的功能,抓取一个块的源代码作为其中的一部分,您可以看到如何甚至重用依赖于Ryan Davis的RubyParser以及一些非常有趣的源文件的代码。您必须修改它以使用Methodsource_location,并可能调整一些其他内容,使其包含或不包含def 顺便说一句,我认为Rubinius内置了这个功能。由于某种原因,它被排除在标准Ruby实现之外,因此出现了这种攻击
哦,我喜欢里面的一些东西!像Chunk一样,不断地对源代码行进行修饰,直到你不再出现解析错误…下面是如何从ruby打印源代码:
puts File.read(OBJECT_TO_GET.method(:METHOD_FROM).source_location[0])
内部方法没有源或源位置,例如Integerto_ 没有依赖关系 如果希望更方便地使用此方法,可以打开方法类: 然后调用method.source 使用Pry,您可以使用show方法查看方法源代码,甚至可以看到一些安装了Pry文档的ruby c源代码,Pry在 注意,我们还可以使用 撬动文档插件;我们还展示了show方法的替代语法:
pry(main)> show-method Array#select
From: array.c in Ruby Core (C Method):
Number of lines: 15
static VALUE
rb_ary_select(VALUE ary)
{
VALUE result;
long i;
RETURN_ENUMERATOR(ary, 0, 0);
result = rb_ary_new2(RARRAY_LEN(ary));
for (i = 0; i < RARRAY_LEN(ary); i++) {
if (RTEST(rb_yield(RARRAY_PTR(ary)[i]))) {
rb_ary_push(result, rb_ary_elt(ary, i));
}
}
return result;
}
所有这些对我来说都是产生了一个分割错误如何再现seg故障?哪个方法/类?我总是错过Ruby中的这个特性。Lisp可以做到这一点:来自Clojure的源代码。这与预期的一样。我收到以下错误:[1]prymain>RSpec.method:class_exec.source MethodSource::SourceNotFoundError:找不到class_exec的源!from/home/vagrant/.bundle/foo/ruby/2.5.0/gems/method_source-0.9.2/lib/method_source.rb:24:in'source_helper'RSpec.method:to_json.source_location工作得很好,我来自未来,使用ruby 2.6.1!我想要Stringinclude?的源代码?。到目前为止,String.instance\u method:include?.source\u location返回nil。对于method类中的源方法来说,这是个好主意。如果它能处理文本,并在什么时候停止打印,那就更好了,因为它已经到达了方法的末尾。
puts File.read(OBJECT_TO_GET.method(:METHOD_FROM).source_location[0])
require 'method_source'
User.method(:last).source
User.method(:last).source_location
method = SomeConstant.method(:some_method_name)
file_path, line = method.source_location
# puts 10 lines start from the method define
IO.readlines(file_path)[line-1, 10]
# ~/.irbrc
class Method
def source(limit=10)
file, line = source_location
if file && line
IO.readlines(file)[line-1,limit]
else
nil
end
end
end
pry(main)> show-method Array#select
From: array.c in Ruby Core (C Method):
Number of lines: 15
static VALUE
rb_ary_select(VALUE ary)
{
VALUE result;
long i;
RETURN_ENUMERATOR(ary, 0, 0);
result = rb_ary_new2(RARRAY_LEN(ary));
for (i = 0; i < RARRAY_LEN(ary); i++) {
if (RTEST(rb_yield(RARRAY_PTR(ary)[i]))) {
rb_ary_push(result, rb_ary_elt(ary, i));
}
}
return result;
}