オンザフライでソースコードをメソッドで取得できるかどうか、およびこのメソッドが含まれるファイルを取得できるかどうかを知りたいです。
お気に入り
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ではこのメソッドは存在しませんが、このgemを使用できます。
今のところ、メソッドのソースコードをオンザフライで表示する方法はありません。
John Mair(Pryのメーカー)による素晴らしい 'method_source' gemを使用する場合、実際には非常に簡単です。メソッドはRuby(Cではなく)で実装する必要があり、ファイル(irbではない)からロードする必要があります。
以下は、method_sourceを使用して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
以下も参照してください。
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
正常に動作します
依存関係なし
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
と、メソッドソースを表示できます。またpry-doc
、codde-browingのPryのドキュメントによると、インストール済みのruby cソースコードも表示できます。
pry-docプラグインを使用して(Ruby Coreから)Cメソッドを表示することもできます。また、show-methodの代替構文も示します。
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; }
source
は、Method
クラス内のメソッドにとって素晴らしいアイデアです。メソッドの最後に達したため、テキストを処理し、印刷を停止するタイミングが新しい場合は、さらに良いでしょう。
この目的のために「ri_for」gemを作成しました
>> require 'ri_for'
>> A.ri_for :foo
...ソース(および1.9を使用している場合は場所)を出力します。
GL。-r
Wrongの一部として同様の機能(ブロックのソースを取得)を実装する必要があり、chunk.rb(Ryan DavisのRubyParserに依存しているだけでなく、かなり面白いもの)でその方法(そしておそらくコードを再利用すること)を確認できますソースファイルグロミングコード)。あなたはそれを使用するために修正しMethod#source_location
、おそらく他のものを微調整して、それが含まれるか含まれないようにする必要がありますdef
。
ところで、Rubiniusにはこの機能が組み込まれていると思います。何らかの理由でMRI(標準のRuby実装)から除外されているため、このハックが行われました。
おお、method_sourceの中のいくつかのものが好きです!以下のような式が有効であるかどうかを伝えるためにevalを使用して(とチャンクがないようにあなたは、パースエラーが発生して停止するまでglommingソース行を保ちます)...
String#include?
。これまでにString.instance_method(:include?).source_location
戻りますnil
。