Development Tip

메서드의 소스 코드를 어떻게 동적으로 가져올 수 있으며이 메서드가 어떤 파일에 있는지

yourdevel 2020. 10. 11. 11:28
반응형

메서드의 소스 코드를 어떻게 동적으로 가져올 수 있으며이 메서드가 어떤 파일에 있는지


소스 코드를 즉시 메서드로 가져올 수 있는지, 그리고이 메서드가 어떤 파일에 있는지 알 수 있는지 알고 싶습니다.

처럼

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 

또한보십시오:


루비에서 소스 코드를 출력하는 방법은 다음과 같습니다.

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메소드 소스를 볼 수 pry-doc있으며 코드 브라우징 의 pry의 문서에 따라 설치된 일부 루비 C 소스 코드도 볼 수 있습니다.

Note that we can also view C methods (from Ruby Core) using the pry-doc plugin; we also show off the alternate syntax for 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;
}

I created the "ri_for" gem for this purpose

 >> require 'ri_for'
 >> A.ri_for :foo

... outputs the source (and location, if you're on 1.9).

GL. -r


I had to implement a similar feature (grab the source of a block) as part of Wrong and you can see how (and maybe even reuse the code) in chunk.rb (which relies on Ryan Davis' RubyParser as well as some pretty funny source file glomming code). You'd have to modify it to use Method#source_location and maybe tweak some other things so it does or doesn't include the def.

BTW I think Rubinius has this feature built in. For some reason it's been left out of MRI (the standard Ruby implementation), hence this hack.

Oooh, I like some of the stuff in method_source! Like using eval to tell if an expression is valid (and keep glomming source lines until you stop getting parse errors, like Chunk does)...


Internal methods don't have source or source location (e.g. Integer#to_s)

require 'method_source'
User.method(:last).source
User.method(:last).source_location

참고URL : https://stackoverflow.com/questions/3393096/how-can-i-get-source-code-of-a-method-dynamically-and-also-which-file-is-this-me

반응형