カレーの恩返し

おいしいのでオススメ。

rubocop-ast.wasm を作った

便利そうなツールを作ったという紹介です。
Ruby 30th LT に出したのですが落ちたので供養として書きました。

解決しようと思った課題

Ruby には RuboCop という linter 兼 formatter があります。 RuboCop に元々入っているルール(Cop と呼ばれます)だけでも十分に便利なのですが、自身の Ruby プロジェクトに合わせて独自のルール(Custom Cop)を作ることができます。

Custom Cop の作り方:

記事に書かれているように、 ちょっとした実装で Custom Cop が作れるようになっています。しかし、自分を含む普段 Web アプリケーションを作っているエンジニアには親しみの薄い概念が登場します。それは S式(AST)です。*1

RuboCop は対象となるプログラムを parse した AST に対して定義されているルールに一致する AST を見つけ、該当箇所に対して linter として怒るという仕組みになっているので、Custom Cop を作るためには AST を表現する必要があることは理解できます。しかし、難しい…

RuboCop に精通した人であれば以下のようなS式を見て

(send
  (send
    (const
      (cbase) :SomeKlass) :new
    (int 1)
    (str "foo")
    (splat
      (send nil :args))) :hoge_method)

「ああ、これはこんなプログラムだな」と理解できるものなのでしょうか。自分には難しすぎる…

::SomeKlass.new(1, "foo", *args).hoge_method

こういった難しさには既視感があるなと思い、思い出したのが正規表現でした。自分も最初は正規表現にとっつきにくさを感じ悪戦苦闘しながら使っていましたが、今ではある程度簡単な正規表現であれば「ああ、こういう文字列とマッチしそうだな」と理解できるようになっています。

なぜそうなったかで思い出すと、体が覚えるまで 正規表現を書いてみる → テスト文字列と一致しているか確かめる → 正規表現を修正する → ... といったトライアンドエラーを繰り返すのが有効だったように思います。

とっつきにくい RuboCop の AST(S式)に対して楽にトライアンドエラーを繰り返せるようになることで、正規表現と同様に「気付いたらなんとなく理解できるようになっている」状態にするにはどうしたらいいか?を考え始めました。

既存の解決方法

既存の方法としては、RuboCop の Cop の実装について - Qiita で紹介されている pocke/rpr が挙げられます。これはプログラムを渡すとS式を返すコマンドラインツールで、以下のような使い方ができます。

% rpr -e "::SomeKlass.new(1, "foo", *args).hoge_method" -p rubocop
s(:send,
  s(:send,
    s(:const,
      s(:cbase), :SomeKlass), :new,
    s(:int, 1),
    s(:send, nil, :foo),
    s(:splat,
      s(:send, nil, :args))), :hoge_method)

上級者がパッとS式を確認するのにピッタリなツールのように感じました。しかし、初学者観点だと以下のような特性も持ち合わせているとより使い勝手の良いツールになりそうだと考えました。

  1. プログラムからS式への変換だけでなく、S式から一致するテストプログラムを確かめられる双方向性
  2. 入力するたびに変換が行われるようなインタラクティブ

1,2 の特性を踏まえると、コマンドラインツールよりも Web ツールの方が良さそうです。 そこで、1,2 の特性の持つ Web ツールを作成してみることにしました。 また、個人的なチャレンジとして Ruby 3.2 からの wasm サポートを利用し frontend で完結するスタンドアローンな Web ツールを目指しました。

作ったもの

rubocop-ast.wasm を作成しました。

ソースコード: https://github.com/euglena1215/rubocop-ast.wasm

プログラムを渡すとS式に変換する機能とS式とテストプログラムを渡すと一致するテストプログラムを教えてくれる機能を提供しています。どちらの機能も一文字入力を行うごとに変換・検証が行われるので、楽にトライアンドエラーを繰り返すことができます。 このツールを使うことで、S式も正規表現と同様に「気付いたらなんとなく理解できるようになっている」になれると考えています。

ツール名の通り、このツールは wasm を使ってブラウザ上で Ruby を動かしているのでバックエンドの管理が必要ないことも個人開発をする上では嬉しいポイントの1つです。 wasm を使ってブラウザで Ruby を動かす流れについては別途ブログに書く予定です。

(TODO: wasm を使ってブラウザで Ruby を動かす流れについての記事リンクを貼る)

感想

Ruby 3.2 で wasm がサポートされたことにより、ちょっとした CLI の Web ツール化が進むのではないかと感じました。
初学者にとって、コマンドラインツールよりも Web ツールの方が嬉しいことは色々あるんじゃないかと思っています。Web ツール化が進むことで Ruby コミュニティの裾野が広がったらいいですね。

参考にさせていただきました

*1:Lisp を普段から使っているエンジニアは別