🙆

Ruby で Method オブジェクトからソースコードを取得する

2024/09/01に公開

Ruby で特定の複数のモデルから特定のメソッドのコードを抜き出したかったので『機械的に Method オブジェクトからコードを取得する』をやってみました。

def any_method(a, b)
  result = a + b
  if result.even?
      "偶数"
    else
      "基数"
  end
end


node = RubyVM::AbstractSyntaxTree.of(method(:any_method), keep_script_lines: true)

puts "#{node.source}"
__END__
output:
def any_method(a, b)
  result = a + b
  if result.even?
    "偶数"
  else
    "基数"
  end
end

こんな感じで Method オブジェクトから RubyVM::AST を生成して、そこからソースコードを抽出することで実現できます。
ちなみに UnboundMethod でも同様にできるんですがこっちの場合は1行目のインデントがズレるので注意が必要です。

class X
  def any_method(a, b)
    result = a + b
    if result.even?
      "偶数"
    else
      "基数"
    end
  end
end

node = RubyVM::AbstractSyntaxTree.of(X.instance_method(:any_method), keep_script_lines: true)

# 1行目のみインデントがない
puts "#{node.source}"
__END__
output:
def any_method(a, b)
    result = a + b
    if result.even?
      "偶数"
    else
      "基数"
    end
  end
GitHubで編集を提案

Discussion