Ripperをコマンドラインから簡単に使うラッパー rpr を作った
RubyGems: rpr | RubyGems.org | your community gem host
作った動機
私は現在仕事としてSideCIというコードレビューを自動化するサービスを開発しています。
SideCIではRubocopなどの静的解析ツールを使用しています。
静的解析ツールの拡張の作成を中心としたRubyの構文に絡むプログラムの作成において、RubyのASTを確認したくなることが多々あります。
そのような時は、以下のようなワンライナーを実行することでRubyコードのASTを表示していました。
$ ruby -r ripper -r pp -e 'pp Ripper.sexp(ARGF.read)' test.rb [:program, [[:command, [:@ident, "puts", [1, 0]], [:args_add_block, [[:string_literal, [:string_content, [:@tstring_content, "Hello world!", [1, 6]]]]], false]]]]
こうすることにより目的は達成されますが、毎回このコマンドを打つのは少々面倒です。
また、ただ表示するだけでなく、pry
を使用して対話的にASTを旅したいことも多々あります。
そのため、今回 rpr というコマンドラインツールを作成しました。
インストール
rpr は gem としてリリースされています。
gem コマンドを使用してインストールして下さい。
$ gem install rpr
使い方
先ほどのワンライナーと同様のことは、以下のようにrpr
コマンド単体で実行することが可能です。
$ rpr test.rb [:program, [[:command, [:@ident, "puts", [1, 0]], [:args_add_block, [[:string_literal, [:string_content, [:@tstring_content, "Hello world!", [1, 6]]]]], false]]]]
これだけでも打鍵数が少なくなって有用ですが、rpr
はformatterオプションによってASTを出力する形式を変更することが可能です。
rpr
は、3つのformatterオプションを選択することが出来ます。
デフォルトではpp
が有効になっています。
-f
か --formatter
として指定します。
pp
これがデフォルトです。
$ rpr --formatter pp test.rb [:program, [[:command, [:@ident, "puts", [1, 0]], [:args_add_block, [[:string_literal, [:string_content, [:@tstring_content, "Hello world!", [1, 6]]]]], false]]]]
json
$ rpr --formatter json test.rb [ "program", [ [ "command", [ "@ident", "puts", [ 1, 0 ] ], [ "args_add_block", [ [ "string_literal", [ "string_content", [ "@tstring_content", "Hello world!", [ 1, 6 ] ] ] ] ], false ] ] ] ]
ASTをJSONとして吐き出します。
pry
$ rpr --formatter pry test.rb [1] pry(#<Array>)> self => [:program, [[:command, [:@ident, "puts", [1, 0]], [:args_add_block, [[:string_literal, [:string_content, [:@tstring_content, "Hello world!", [1, 6]]]]], false]]]] [2] pry(#<Array>)> exit
ASTをselfとしてpryを起動します。
これにより、対話的にASTを参照することが可能なため、ASTの構造を把握するのに役立つでしょう。
その他
--method
オプションにてsexp
の代わりにtokenize
を使用したり、--out
オプションにて出力先のファイルを指定することも可能です。
また、設定ファイル機能などを今後増やしていく予定です。
まとめ
RubyのASTを旅するGem、rprの紹介でした。
いかがでしたでしょうか?
RubyのASTを参照する機会が多い方は、是非一度試してみて下さい。