Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

1 Ruby AST とは

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

2 習うより慣れる

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

ちょっと宣伝

Slide 34

Slide 34 text

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