読者です 読者をやめる 読者になる 読者になる

pockestrap

Web Programmer's memo

Ripperをコマンドラインから簡単に使うラッパー rpr を作った

github.com

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を参照する機会が多い方は、是非一度試してみて下さい。