気になっていた。メタプロ。
感想を書いていく。
はじめに
RubyやRuby on Railsを使いたい人は読むといいぽい
メタプログラミングはLispからやってきたもの。
I部では、
メソッド検索、Rubyのクラス
lambda
スコープ
Ⅱ部では、
メタプログラミングのケーススタディ
Ruby上級者向けの本ではないぽい
第2章
2-1.オープンクラス
メソッドが文字列でしか使われないと明確なため、Stringクラスに変更
|
|
2-1.1 クラス定義の内部
Rubyのclassは、クラス宣言というよりスコープ演算子のようなもの。
オープンクラス
という。
ただStringとかを書き換えるモンキーパッチは危険そう。(感想)
[Ruby] メタプログラミングの入り口、オープンクラスを理解する
2.1.2 Monetizeの例
Monetize
というgemを利用してオープンクラスを確認した
2.1.3 オープンクラスの問題点
replaceメソッドを定義しArrayクラスに寄せたが、すでにArrayにreplaceが元から生えているため、壊れる。モンキーパッチの悪い例
2-2 オブジェクトモデルの構造
クラスやオブジェクトのクラスには見た目以上に隠されているものが多い
2.2.1 オブジェクトの中身
同じメソッドでも、クラスに着目しているときはインスタンスメソッド
で、 オブジェクトに着用しているときはメソッド
と呼ぶ
|
|
2.2.2 クラスの真相
クラスはオブジェクトである
|
|
すべてのクラスはModule
|
|
2.2.3 定数
定数と変数の違いは、スコープ。
2.2.4 オブジェクトとクラスのまとめ
オブジェクトのメソッドは、オブジェクトではなくオブジェクトのクラスに住んでいて
クラスのインスタンスメソッドと呼ばれる
クラスとは、オブジェクトにインスタンスメソッドの一覧とスーパークラスへの
リンクがついたものである
ここらへんこんがらがるからまた読み返したい
2.2.5 ネームスペースを使う
Action Mailer には Text クラスがあるので、
自前で Textクラスを実装することは出来ないが、moduleでラップすればいける
2.4 メソッドを呼び出すときに何がおきているのか
メソッドを探す時、Rubyは以下のことを行う
1.メソッドを探す これはメソッド検索と呼ばれる
2.メソッドを実行する これにはselfと呼ばれるものが必要
2.4.1 メソッド探索
karnel は Objectから継承されており、printがどこでも使えるよねという説明
2.4。2 メソッドの実行
メソッドはレシーバのオブジェクトに依存する
2.4.3 Refinements
https://docs.ruby-lang.org/ja/latest/method/Module/i/refine.html
3からはrefine になったっぽい。
2-6 まとめ
学んだことが羅列されている。
2章はここだけ復習すればよさそう
クラス、継承、インスタンス変数、メソッド、モジュール、レシーバ、あたり
Rubyのオブジェクトの実態など
3章 メソッド
動的言語はコンパイラ時にエラーが出ない。
3.2.1 メソッドを動的に呼び出す
send
を使うと得られるメリット → 動的ディスパッチ(コード実行時に呼び出すメソッドを決められる)
|
|
上記の例だとmy_methodがメソッド名、my_argsが引数。
my_methodの箇所を変数に変えればメソッド名は自由自在。
ゴーストメソッド
さらに「この名前で定義してね」とお願いするだけではなく「知らないメソッド名がきたらこの処理をしてね」ということもできる。
method_missingをオーバーライドすることでメソッド名が存在しない場合の処理を記載できる。
これを使う場合、respond_to_missing?メソッドもオーバーライドしてゴーストメソッドがrespond_to?に正しい値を返すようにするのがルール。ただ暗黙のルールとなっているため動的メソッドで済む場合はそちらを使った方がバグが入ってきづらい。
3.2.2 Pryの例
スパイダーマンのベンおじさんの 「大いなる力には、大いなる責任が伴う」がでてきて胸アツ
例では send
はprivateも呼び出せるから強力すぎるといったことを説明している
3-6 まとめ
動的メソッドと動的ディスパッチ
repond_to? method_missing
ゴーストメソッド
あたりの話。途中の 3-5あたりまでスキップ
4章 ブロック
4.1.2 ブロックの基本
|
|
メソッドはyieldを使ってブロックをコールバックする。
4.5.1 proc と lambda
Procはブロックをオブジェクトにしたもの
|
|
上記は遅延評価?
&演算子と、procと、Object#method について理解しなおす
&修飾は復習が必要そう
Procをlambdaの明確な違い
・return キーワードの意味が違う
・引数に関するチェック
Procの場合は、Procが定義されたscopeから戻る。
lambdaの方が、引数の扱いに厳しい
lamdbaでも同じように作れるがprocでよさそうと思っていたが、書籍ではlambda推しだった
クラス定義
モジュール定義
メソッド
という単位で切り替わる。
4-8 まとめ
スコープゲートとはなにか
フラットスコープと共有スコープを使い、スコープを横断して束縛を見えるようにする
オブジェクトのスコープで、コードを実行する方法や、クリーンルームでコードを実行する方法
ブロックとオブジェクトを相互に変換する方法
メソッドとオブジェクトを相互に変換する方法
呼出し可能オブジェクトの種類とその地以外 通常とのメソッドとの違い
独自の小さなDSLの書き方
正直この章むずかったので復習したい
第5章 クラス定義
Rubyのクラス定義は、実際にコードを実行している
この章では、クラスマクロとアラウンドエイリアスを学ぶ。
クラスマクロ
attr_accsessorのようなキーワードに見えるクラスメソッドの事
特異メソッド 特異クラス
1つのインスタンス固有のメソッドのことだけが使えるメソッドのこと
オブジェクトの7つのルール
オブジェクトは1種類のみ: 通常のオブジェクトかモジュールになる
モジュールは1種類のみ: 通常のモジュールかクラス、特異クラスのいずれかになる
メソッドは1種類のみ: モジュールに住んでいる
全てのオブジェクトは「本物のクラス」を持つ: 通常クラスか特異クラスのどちらか
(BasicObject以外の)全てのクラスは1つの祖先を持つ: スーパークラスかモジュール
オブジェクトの特異クラスのスーパークラスはオブジェクトのクラス、クラスの特異クラスのスーパークラスはクラスのスーパークラスの特異クラス
メソッド探索はまず「本物のクラス」に向かって「右に」進み、その後継承チェーンを辿って「上に」進む
クラスメソッドの構文
|
|
3番目の、特異クラスをオープンして、そこにメソッド 定義している
instance_eval
nstance_evalは、オブジェクトの特異クラスにインスタンスメソッドを定義したり、そのオブジェクト自身が参照できるインスタンス変数を定義、または上書きしたりすることができる。
instance_evalとclass_evalについての備忘録
instance method Object#extend
イマイチぴんときてない。。
引数で指定したモジュールのインスタンスメソッドを self の特異メソッドとして追加します。
Module#include は、クラス(のインスタンス)に機能を追加しますが、extend は、ある特定のオブジェクトだけにモジュールの機能を追加したいときに使用します。
引数に複数のモジュールを指定した場合、最後の引数から逆順に extend を行います。
アラウンドエイリアス
アラウンドエイリアスとは再定義したメソッドから以前のメソッドをエイリアスとして呼び出すことです。
・元の処理の前後に処理を追加したり
・ラップした処理を作成したり
・既存機能を拡張しつつ、元のメソッドも利用可能にしたり
と便利。
しかし、既存処理を利用箇所がある場合は影響範囲の見極めが必要
確かにStringやIntの元のメソッド変えると大変なことになるね
|
|