LoginSignup
14
8

More than 5 years have passed since last update.

Ruby でクラスのソースを表示するコード

Last updated at Posted at 2017-09-25

rubyにはメソッドのソースを取得する method_source というgemがあるのですが、これのクラスバージョンもあったら便利かも?と思って書いてみました。

class_sources.rb
module ClassSource
  @lines_for_file = {}
  @locations = Hash.new { |h, k| h[k] = [] }
  @pos_stack = []

  TracePoint.trace(:class, :end) do |tp|
    next if tp.self == ClassSource
    @lines_for_file[tp.path] ||= File.readlines(tp.path)

    case tp.event
    when :class
      @pos_stack << tp.lineno - 1
    when :end
      from, to = @pos_stack.pop, tp.lineno - 1
      content = @lines_for_file[tp.path][from..to].join
      @locations[tp.self] << { path: tp.path, from: from, to: to, content: content }
    end
  end

  def self.locations(klass)
    @locations[klass]
  end
end

class Object
  def source_locations
    ClassSource.locations(self)
  end
end

class A
  def say
    "hi"
  end
end

A.source_locations.each do |data|
  puts "#{data[:path]}##{data[:from]}"
  puts "-" * 30
  puts data[:content]
  puts "-" * 30
end

出力

class_sources.rb#30
------------------------------
class A
  def say
    'hi'
  end
end
------------------------------

TracePoint が実行される前のクラス定義は無視されてしまうのが難点です。

14
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
8