Я хотел бы знать, могу ли я получить исходный код метода на лету и могу ли я узнать, в каком файле находится этот метод.
нравиться
A.new.method(:a).SOURCE_CODE
A.new.method(:a).FILE
Использование source_location
:
class A
def foo
end
end
file, line = A.instance_method(:foo).source_location
# or
file, line = A.new.method(:foo).source_location
puts "Method foo is defined in #{file}, line #{line}"
# => "Method foo is defined in temp.rb, line 2"
Обратите внимание, что для встроенных методов source_location
возвращает nil
. Если вы хотите проверить исходный код C (получайте удовольствие!), Вам нужно будет найти правильный файл C (они более или менее организованы по классам) и найти rb_define_method
метод (ближе к концу файла ).
В Ruby 1.8 этого метода не существует, но вы можете использовать этот гем .
String#include?
. ПокаString.instance_method(:include?).source_location
возвращаетсяnil
.Ни один из ответов пока не показывает, как отображать исходный код метода на лету ...
На самом деле это очень просто, если вы используете замечательный гем method_source от Джона Мэра (создателя Pry): метод должен быть реализован на Ruby (а не на C) и должен быть загружен из файла (не irb).
Вот пример, показывающий исходный код метода в консоли Rails с помощью method_source:
$ 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
Смотрите также:
источник
source
. Это работает, как ожидалось.[1] pry(main)> RSpec.method(:class_exec).source
MethodSource::SourceNotFoundError: Could not locate source for 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:
puts File.read(OBJECT_TO_GET.method(:METHOD_FROM).source_location[0])
источник
Без зависимостей
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]
Если вы хотите использовать это более удобно, вы можете открыть
Method
класс:# ~/.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
А потом просто позвони
method.source
С помощью Pry вы можете использовать
show-method
для просмотра источника метода, и вы даже можете увидеть некоторый исходный код ruby c сpry-doc
установленным, согласно документу pry в codde-browingисточник
source
метода внутриMethod
класса. Было бы даже лучше, если бы он обработал текст и новый, когда прекратить печать, потому что он достиг конца метода.Я создал для этого гем "ri_for"
>> require 'ri_for' >> A.ri_for :foo
... выводит источник (и местоположение, если вы используете 1.9).
GL. -р
источник
Мне пришлось реализовать аналогичную функцию (захватить источник блока) как часть Wrong, и вы можете увидеть, как (и, возможно, даже повторно использовать код) в chunk.rb (который опирается на RubyParser Райана Дэвиса, а также на довольно забавные исходный файл glomming code ). Вам придется изменить его, чтобы использовать
Method#source_location
и, возможно, настроить некоторые другие вещи, чтобы он включал или не включалdef
.Кстати, я думаю, что в Rubinius встроена эта функция. По какой-то причине она была исключена из MRI (стандартной реализации Ruby), отсюда и этот взлом.
Ооо, мне нравятся некоторые вещи в method_source ! Это похоже на использование eval, чтобы определить, допустимо ли выражение (и продолжайте показывать исходные строки, пока вы не перестанете получать ошибки синтаксического анализа, как это делает Chunk) ...
источник
Внутренние методы не имеют источника или местоположения источника (например
Integer#to_s
)require 'method_source' User.method(:last).source User.method(:last).source_location
источник