Techioz Blog

Ruby ファイルから Pry の show-source メソッドにアクセスする

概要

Ruby ファイル内から Pry の show-source メソッドにアクセスすることは可能ですか?もしそうなら、これはどのように行われますか?

たとえば、次のファイルがあるとします。

# testing.rb

require 'pry' 

def testing
  puts 'hi'
end

puts show-source testing

そして、ruby testing.rbを実行しました。出力は次のようになります。

Owner: testing.rb
Visibility: public
Number of lines: 3

def testing
  puts 'hi'
end

この理論的根拠を説明するために、メソッドをスタブ化するテストを用意しました。ただし、元のメソッドは時々呼び出されているようで、呼び出しのソースを出力して、呼び出し元を確認するのが便利だと思いました。これを行うためのより簡単な方法があることは知っていますが、最初はウサギの穴から始めたので、これができるかどうかを確認することに興味があります:)

少し頭をひねる show-source show-source を実行すると、Pry::Command::ShowInfo を継承する Pry::Command::ShowSource クラス内のメソッドがいくつか表示されます。

Pry::Command::ShowSource には、options、process、content_for という 3 つのメソッドが表示されますが、どれも正常に呼び出すことができませんでした。

私の最善の仮定は、 content_for メソッドがこれを処理し、親クラスから割り当てられたコードオブジェクト(つまり、 Pry::CodeObject.lookup(obj_name, pry, :super => opts[:super]) )を操作することです。これを突破することができました。

これを行うアイデアや例がある人はいますか?

解決策

Ruby には、ソースの場所を見つけるために使用できる組み込みメソッド Method#source_location があります。 Method_source gem は、ソースの場所に基づいてソースを抽出することで、これに基づいて構築されます。ただし、これは対話型コンソールで定義されたメソッドでは機能しません。メソッドはファイル内で定義する必要があります。

以下に例を示します。

require 'set'
require 'method_source'

puts Set.method(:[]).source_location
# /home/user/.rvm/rubies/ruby-2.4.1/lib/ruby/2.4.0/set.rb
# 74
#=> nil

puts Set.method(:[]).source
# def self.[](*ary)
#   new(ary)
# end
#=> nil

すべてのコアの Ruby メソッドは C で書かれており、ソースの場所として nil を返すことに注意してください。 1.method(:+).source_location #=> nil 標準ライブラリは Ruby 自体で書かれています。したがって、上記の例は Set メソッドに対して機能します。