Upgrade to Pro — share decks privately, control downloads, hide ads and more …

習うより慣れる Ruby AST / Ruby AST is better to get used to than to learn.

習うより慣れる Ruby AST / Ruby AST is better to get used to than to learn.

omotesando.rb#94 で発表したスライドです。
https://omotesandorb.connpass.com/event/308359/

rubocop-ast.wasm
https://rubocop-ast-wasm.vercel.app/

Shintani Teppei

February 01, 2024
Tweet

More Decks by Shintani Teppei

Other Decks in Programming

Transcript

  1. 2024/02/01 【オフライン開催】Omotesando.rb #94
    株式会社タイミー 新谷哲平
    習うより慣れる Ruby AST
    @euglena1215

    View full-size slide

  2. 自己紹介
    新谷 哲平(@euglena1215)
    ● 株式会社タイミー
    ● バックエンドエンジニア
    ● ホットなGemは packwerk
    ● すき焼きのたれで肉じゃがを
    作れることを知ってずっと作ってます

    View full-size slide

  3. 2024/02/01 【オフライン開催】Omotesando.rb #94
    株式会社タイミー 新谷哲平
    習うより慣れる Ruby AST
    @euglena1215

    View full-size slide

  4. どんな人向けの発表?
    Ruby AST に親しみがない人向け
    Ruby AST を見たときに身構えないようになることがゴール。

    View full-size slide

  5. こうなるといいな
    Ruby AST わからないし、
    多分わかるようになることはないだろう

    View full-size slide

  6. こうなるといいな
    Ruby AST わからないけど、
    頑張ったらわかるようになりそう!

    View full-size slide

  7. 目次
    ● Ruby AST とは
    ● 習うより慣れる
    ● ちょっと宣伝

    View full-size slide

  8. 1 Ruby AST とは

    View full-size slide

  9. AST = Abstract Syntax Tree(抽象構文木)
    例えば、右の図だと 2 * (1 + 3) に対応している。
    Ruby プログラムを意味のあるかたまりごと(トーク
    ン)でツリー構造に変換したものが Ruby AST。
    Ruby AST とは

    View full-size slide

  10. AST = Abstract Syntax Tree(抽象構文木)
    例えば、右の図だと 2 * (1 + 3) に対応している。
    Ruby プログラムを意味のあるかたまりごと(トーク
    ン)でツリー構造に変換したものが Ruby AST。
    Ruby AST とは
    今回は直感的に理解するのが目的なので、
    Ruby プログラムをツリー構造で表すなにかくらいの理解で大丈夫。
    (説明しすぎると自分の理解にボロが出るという話もある)

    View full-size slide

  11. ● Ruby プログラムを機械が解釈できるようにする
    ○ ソースコードはあくまで文字列なので、文字列を解釈可能なものに変換する必要がある。
    Ruby AST がどんなところで使われているか

    View full-size slide

  12. ● Ruby プログラムを機械が解釈できるようにする
    ○ ソースコードはあくまで文字列なので、文字列を解釈可能なものに変換する必要がある。
    ● RuboCop
    ○ Ruby プログラムを Ruby AST に変換して、あらかじめ用意しておいた違反しているツリー構
    造と一致しているかどうかをパターンマッチして警告を出している。
    ○ RuboCop のルールを作ること = Ruby AST のパターンマッチを書くこと
    Ruby AST がどんなところで使われているか

    View full-size slide

  13. ● Ruby プログラムを機械が解釈できるようにする
    ○ ソースコードはあくまで文字列なので、文字列を解釈可能なものに変換する必要がある。
    ● RuboCop
    ○ Ruby プログラムを Ruby AST に変換して、あらかじめ用意しておいた違反しているツリー構
    造と一致しているかどうかをパターンマッチして警告を出している。
    ○ RuboCop のルールを作ること = Ruby AST のパターンマッチを書くこと
    ● Packwerk(ここの紹介は割愛する予定)
    ○ 他言語にあるようなパッケージを仮想的に作り、他パッケージで宣言されている定数やクラス
    を自パッケージで参照しているかどうかをチェックし、予期しない依存関係があれば警告を出
    すのが Packwerk。
    ○ パッケージ内での定数・クラスの宣言、定数・クラスの参照は Ruby プログラムを Ruby AST
    に変換した上で集計している。
    Ruby AST がどんなところで使われているか

    View full-size slide

  14. 2 習うより慣れる

    View full-size slide

  15. 習うより慣れる
    最も一般的な parser gem の Ruby AST を使って紹介します。
    ここからは説明して理解するのではなく、感じてもらうスタイルで
    以下3点をセットで紹介していきます。
    ● Ruby プログラム
    ● Ruby AST(S式)
    ● Ruby AST(ツリー構造)

    View full-size slide

  16. リテラル 〜文字列〜
    文字列はこんな感じ。

    View full-size slide

  17. リテラル 〜整数〜
    整数もこんな感じ。

    View full-size slide

  18. リテラル 〜シンボル〜
    シンボルもこんな感じ。

    View full-size slide

  19. メソッド呼び出し〜一番シンプルな形〜
    だんだんとツリー構造になってきた。

    View full-size slide

  20. メソッド呼び出し〜一番シンプルな形〜
    だんだんとツリー構造になってきた。
    メソッド呼び出しは全て send から始まる

    View full-size slide

  21. メソッド呼び出し〜一番シンプルな形〜
    だんだんとツリー構造になってきた。
    some_method のレシーバーは指定されてい
    ないので nil
    レシーバー = メソッドの呼び出し元

    View full-size slide

  22. メソッド呼び出し〜一番シンプルな形〜
    だんだんとツリー構造になってきた。
    メソッド名がくる

    View full-size slide

  23. メソッド呼び出し〜一番シンプルな形〜
    だんだんとツリー構造になってきた。
    最後に引数が入っている

    View full-size slide

  24. メソッド呼び出し〜レシーバーが存在する〜
    レシーバーが追加されたらどうなるか見てみる。

    View full-size slide

  25. メソッド呼び出し〜レシーバーが存在する〜
    レシーバーが追加されたらどうなるか見てみる。
    渡したプログラムでは some_obj が何なのか分からないので
    メソッド呼び出しとして評価されている。

    View full-size slide

  26. メソッド呼び出し〜レシーバーが存在する〜
    レシーバーが追加されたらどうなるか見てみる。
    渡したプログラムでは some_obj が何なのか分からないので
    メソッド呼び出しとして評価されている。
    some_obj メソッドのレシーバーは存在しないので nil になっている。

    View full-size slide

  27. メソッド呼び出し〜ローカル変数を宣言する〜
    some_obj をローカル変数として定義したらどうなるか確認する。

    View full-size slide

  28. メソッド呼び出し〜ローカル変数を宣言する〜
    some_obj をローカル変数として定義したらどうなるか確認する。
    プログラムが複数行になったので先頭に begin がついて
    まとめられるようになった。

    View full-size slide

  29. メソッド呼び出し〜ローカル変数を宣言する〜
    some_obj をローカル変数として定義したらどうなるか確認する。
    lvasgn は local variable assignment の略。(要するにローカル変数の宣言)
    some_obj という変数名に “Some obj” を設定している。

    View full-size slide

  30. メソッド呼び出し〜ローカル変数を宣言する〜
    some_obj をローカル変数として定義したらどうなるか確認する。
    lvar は local variable で、既に宣言されているローカル変数 some_obj を
    参照している。
    1つ前では some_obj はメソッド呼び出しとして評価されていたけど、今回は
    ローカル変数として評価されるようになった。

    View full-size slide

  31. 習うより慣れる
    リテラル、メソッド呼び出し以外にも Ruby にはたくさんの構文があるので
    普段書いているプログラムがどんな AST になっているか興味を持った人は色々
    と調べてみるのがおすすめ。

    View full-size slide

  32. ちょっと宣伝
    AST をちょっと触ってみるためのツールとして以前 Web ツールを作ったので
    宣伝します。
    Ruby プログラムがどんな AST になるのかパッと確認したり、逆に AST に対し
    てどんな Ruby プログラムがマッチするのかを確認できます。
    「rubocop ast wasm」で検索
    https://rubocop-ast-wasm.vercel.app/

    View full-size slide

  33. ちょっと宣伝

    View full-size slide

  34. まとめ
    ● Ruby AST はいろんなところで使われている
    ● リテラルやメソッド呼び出しの AST であれば理解は
    そこまで難しくない
    ● rubocop-ast.wasm を使って他の構文でどうなるかも
    調べてみよう!

    View full-size slide