소스 코드를 즉시 메서드로 가져올 수 있는지, 그리고이 메서드가 어떤 파일에 있는지 알 수 있는지 알고 싶습니다.
처럼
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
있으며 코드 브라우징 의 pry의 문서에 따라 설치된 일부 루비 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. -아르 자형
나는 Wrong의 일부로 유사한 기능을 구현해야했고 (블록의 소스를 잡아 ) chunk.rb (Ryan Davis의 RubyParser에 의존 하는 코드와 코드를 재사용하는 방법)를 볼 수 있습니다. 소스 파일 glomming 코드 ). 당신은 그것을 사용하기 위해 그것을 수정해야 할 Method#source_location
것이고 아마도 다른 것들을 조정하여 def
.
BTW 저는 Rubinius에이 기능이 내장되어 있다고 생각합니다. 어떤 이유로 MRI (표준 Ruby 구현)에서 제외되었으므로이 해킹입니다.
아, method_source 의 내용이 마음에 듭니다 ! 마찬가지로 표현식이 유효한지 말할 평가를 사용하여 (그리고 덩어리가하는 것처럼 당신이, 구문 분석 오류를 받고 중지 할 때까지 glomming 소스 라인을 유지) ...
String#include?
. 지금까지String.instance_method(:include?).source_location
돌아갑니다nil
.