Skip to content

Commit

Permalink
「Rubyのしくみ Ruby Under a Microscope」を読んだ
Browse files Browse the repository at this point in the history
  • Loading branch information
QWYNG committed Apr 23, 2024
1 parent c044b08 commit 56d3fd6
Showing 1 changed file with 79 additions and 14 deletions.
93 changes: 79 additions & 14 deletions content/posts/ruby_no_shikumi.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,96 @@
---
title: "Rubyのしくみを読んだ"
title: "「Rubyのしくみ Ruby Under a Microscope」を読んだ"
date: 2024-04-22T21:44:50+09:00
draft: true
draft: false
---

RubyKaigiも近いということで積読していた[Rubyのしくみ Ruby Under a Microscope
RubyKaigi間近!ということで積読していた[Rubyのしくみ Ruby Under a Microscope
](https://tatsu-zine.com/books/ruby-under-a-microscope-ja)を読んだので感想を書きます。

全部で12章ある本なんですが、自分の中での区切り順で書きます
全部で12章ある本なんですが、自分の中での勝手な区切りで分けて感想を書きます

## 1章, 2章 パースとコンパイル
字句解析、構文解析、コンパイルについて書かれている。
正直、ここが一番よくわかってない。

- 最近のRubyKaigiで熱いパーサーの話
- 字句解析と構文解析という概念がある
- 字句解析は文字列をトークンに分解する
- 構文解析はトークンを構文木に変換する
- 字句解析のステートマシンとか構文木の話を詳しく知りたい人は[アンダースタンディング コンピュテーション](https://www.oreilly.co.jp/books/9784873116976/)を読もう!Rubyからコンピューター最センスが学べちまうんだ!(僕は積んでいます)
- 字句解析のステートマシンとか構文木の話を詳しく知りたい人は[アンダースタンディング コンピュテーション](https://www.oreilly.co.jp/books/9784873116976/)を読もう!Rubyからコンピューターサイエンスが学べちまうんだ!(僕は積んでいます)
- こういう日本語の解説が色々あるのがRubyの強みだよなぁ
- 僕はDeterministic Finite Automatonって響きかっこいいなぁという気持ちしかありません
- すごろくのマス目を進むイメージで理解している
- コンパイル
-
- ASTを更に命令列に変換する処理を説明してくれているのだが、あんまり理解できていない

## 3章, 4章 VMの動作
VMの動作について書かれている。
- 内部スタックとコールスタック
- 院で研究しているプログラムの操作的意味論の[サンプル](https://kframework.org/k-distribution/pl-tutorial/2_languages/2_kool/1_untyped/kool-untyped/
)も環境スタックとコールスタックを2つもつ実装だった。

)も環境スタックとコールスタックを2つ持つ実装だった。
- 二重スタックが入り交じる解説を消化するのは難易度高い
- キーワード引数の内部はハッシュとかforの中身がeachとか知るだけでも面白い話も載っている
- ブロック内で変数をスタック遡って探す話、なぜclassとかdef通すとできないんだ?と思ったけど、第9章に答えが載っていた。

## 5章, 6章 オブジェクト、クラス、メソッド探索
- Rubyのソースコードのあちこちで見かけるVALUEポインタについて書かれている
- 6章のメソッド探索と定数探索の話は特に面白かった
- クラスとモジュールの継承はわりと想像通りだったけど、prependの実装がおもしろかった
- レシーバのクラスのコピーを作ってメソッド全部コピーしたクラスに棚上げするの頭良すぎる
- Ruby利用者からするとprependって組み込みのクラスにパッチ当てたりしやすくなる神機能だけど、実装は結構トリッキーなんだなと思った。
- レキシカルスコープ
- Ruby3.2.2でもレキシカルスコープと継承チェーン内の探索の順序は変わっていなさそう

```ruby
> ~/qwyng.dev on master ◦ irb
irb(main):001* class SuperClass
irb(main):002* FIND_ME = 1
irb(main):003> end
=> 1
irb(main):004* module ModuleA
irb(main):005* FIND_ME = 2
irb(main):006* class SubClass < SuperClass
irb(main):007* p FIND_ME
irb(main):008* end
irb(main):009> end
2
=> 2

> ~/qwyng.dev on master ⨯ ruby -v
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [arm64-darwin22]
```


- この章は実際の開発でも役に立つ知識が多そうだと感じた
- fursich氏の[Rubyの定数が怖いなんて言わせない](https://qiita.com/fursich/items/a1b742795cf10eebc73f#ruby25%E3%81%AE%E9%80%B2%E5%8C%96)という神ドキュメントがあるのですが、Rubyのしくみの5,6章読んでからこのドキュメントを読むとめっちゃ面白いですよ!!

## 7章 ハッシュテーブル
- Object#hashってそんな大事なことに使われてたんだ...
- eql?を独自で実装するときにObject#hashも同じロジックでオーバライドしてねみたいな[ドキュメント](https://docs.ruby-lang.org/ja/latest/method/Object/i/eql=3f.html)があるけど、hashをなぜオーバライドするのかがよくわかった
- 例えば、`a = SomeObj.new; b = SomeObj.new; a.eql?(b) => true`と実装したけど、`a.hash == b.hash => false`だと、ハッシュテーブル内で`a``b`は別のバケットに入ってしまう可能性がある。
- hashメソッドは十分に散らばった値になるようにしないとすぐ同じバケットに値が集まってしまう
- hashメソッドの定義は慎重に行う必要がありそう

## 8章 Lispから借用したアイデア
- 院で先生に「クロージャってなんですか」と聞かれて答えられなかったのを思い出す
- 環境と関数のペアです...安西先生
- lambdaを呼び出すと環境をまるごとヒープに保存するたまげたな
- procとlambdaの違いって引数の厳密性だと思っていたけど、内部でちゃんとフラグを持ってるんですね

## 9章 メタプログラミング
- 特異クラスとメタクラスの違いが書いてあって、メタプログラミングRubyより一歩踏み込んだ解説がなされていた
- Rubyの`class <<` は引数のオブジェクトの特異クラスを作成するという構文っぽい
- `class << self` はselfの特異クラスを作成しているという解釈ができる
- class_evalとかinstance_evalはブロック構造体のselfの変更していたんですね
- メタプログラミングRubyでスコープゲートと呼ばれていたものはレキシカルスコープのことだったのか?
- ブロック内ではレキシカルスコープのポインタ先が違うのが原因っぽい
- defやclassはレキシカルスコープをそのままcref構造体みているが、ブロックだとスタック上のスコープを直接参照している。
- ここでやっと3章で出てきたスタックを遡って変数にアクセスする話が理解できた
- つまりRubyのブロックはダイナミックスコープなんだよ!!!!Lispと一緒でレキシカルスコープもダイナミックスコープもある!!!!
- この本、コラムっぽいページに大事な内容が書かれているので、読み飛ばさないように注意が必要


## 10章、11章
- 飛ばしました....

## 12章 GC
- GCのアルゴリズムが色々あることがわかったぜ!!!

## 全体通しての感想
最初の命令列とかスタックの動作はかなり理解が難しかった(今もそんなにわかってない)が、中盤のクラスとかメソッド探索の話は普段の業務でも役にたつことが多そうだと思った。
正直、このしょうもない感想記事に書いてあることの10000倍くらい濃い情報が本には書かれているので、興味がある人はぜひ読んでみてください。(もうRubyも3.3なので、この本の内容が古くなっている可能性もあるけど)

0 comments on commit 56d3fd6

Please sign in to comment.