概要
現在Rubyを勉強しており、「Rubyを勉強するならメタプログラミングRubyは必読!」という先輩からの教えがあり、読んでいるのでそれのまとめメモです。
筆者のRubyに関してのスキルは「プロになるためのRuby」を読んでRailsチュートリアルをさらっとくらいのレベルです。
お見知り置きいただければと。。。
今回はまずメタプログラミングに関してまとめようと思います。
個人的レベル感
「上級者向け過ぎてわからないことも多いだろうなあ」とびびっていたのですが案外わかりやすく、ひとつひとつコードを書きながら進めていくと理解が進むような造りになっていると感じました。
翻訳書なので、表現の仕方が基本的に海外よりなので、そこに関して苦手な人は読みづらいかもです...
何かあるごとに開く本というのが誰しもあると思うのですが、個人的にはこの本はそこにランクインするレベルだと思います。
そもそもメタプログラミングって何?(広い意味での)
- ロジックを直接コーディングするのではなく、あるパターンをもったロジックを生成する高位ロジックによってプログラミングを行う方法、またその高位ロジックを定義する方法のこと( wikipedia)
- 他のプログラム ( あるいは自身 ) を操作したり出力するプログラムを書くこと、または作業の一部をコンパイル時に行い、残りの作業を実行時に行うようなプログラムを書くことである。
- コードジェネレータやコンパイラが行うコード生成のこと。
Rubyは「動的メタプログラミング」
- Rubyに関して言えば、「コードを生成するためのコードを書くこと」が簡単にできてしまう。
(本書の言葉を借りれば「シームレスかつエレガントに」) - 「魔法」や「黒魔術」と呼ばれるくらい、簡潔にコードが書ける。
- 「大いなる力には、大いなる責任が伴うことを忘れてはいけない」 by Matz
言語要素を実行時に操作するコードを記述すること
コードジェネレータやコンパイラが行うコード生成のことも、「広い意味でのメタプログラミング」と言えるのだが、Rubyはこの定義には含まれない。
これを「静的メタプログラミング」と呼ぶならば、Rubyは「動的メタプログラミング」と呼べる
メタプログラミングに利用されている技術の例
実際に本書で使われている技術の一例を紹介しようと思います。
※ もっと沢山あります。
既存のクラスの振る舞いを変更する(モンキーパッチ)
"abc".reverse # => "cba"
class String
def reverse
"オーバーライド"
end
end
"abc".reverse # => "オーバーライド"
1. 再定義したメソッドから以前のメソッドをエイリアスで呼び出す
# String#reverseに新たな機能を追加する
"abc".reverse # => "cba"
class String
alias_method :old_reverse, :reverse
def reverse
"hoge#{old_reverse}hoge"
end
end
"abc".reverse # => "hogecbahoge"
2. 該当するメソッドのないメッセージに応答する
class Hoge; end
hoge = Hoge.new
hoge.no_define_method
# => NoMethodError (undefined method `no_define_method' for #<Hoge:0x00007f9649836be8>)
# BasicObject#method_missingを書き換える(noMethodErrorを返しているメソッド)
class Hoge
def method_missing(name, *args)
name.to_s.reverse
end
end
hogehoge = Hoge.new
hogehoge.no_define_method
# => "hogedohtem_enifed_onhoge"
動的メソッド
class C; end
C.class_eval do
define_method :my_method do
"動的メソッド"
end
end
obj = C.new
obj.my_method
# => "動的メソッド"
ざっくりまとめると
- 上記のようなRubyの技術を駆使してコードのリファクタなどを例を用いてわかりやすく説明してくれています。
- ActiveRecordなどのRailsのコードもどのようなスキルを駆使して書かれているか説明してくれているので、難しいコードを読んだことない人にとってはとっつきやすいかもしれません。
- 本書の最後のほうでも言っているのですが、メタプログラミングがどうとか考えずにただのプログラミングだと思えという言葉がなぜかしっくりきました。
(自分のバイアスがかかっていただけかも?) - Rubyの「特徴」を事細かに説明してくれている良書だと思います。