出版社より献本御礼。
「ただの」プログラマーで終わりたくない人、必携。
Rubyistsはもとより、そうでない人も。
むしろRuby以外のプログラミング言語をホームグラウンドにしている人は、Rubyistsよりもさらに得るところが大きいかもしれない。「私の言語ではどうやる?」を考え、実際にやってみることで、Rubyも「母国語」も理解が深まるのだから。
本書「メタプログラミングRuby」は、Rubyにおけるメタプログラミングを物語形式で学ぶ一冊。舞台はRubyを使っているある会社。平凡なプログラマー、ボブは、いかにしてメタプログラマーへと一週間で成長したか。
目次
|
|
メタプログラミング(metaprogramming)とは、何か。
プログラムを書くのがプログラミングなら、プログラムを書くプログラムを書くのがメタプログラミングということになる。なんだかすごそうで、すごくこわそうな話であるが、実はそれほど特別な話ではない。また、動的言語に限った話でもない。Makefileを編集するというのはある意味メタプログラミングだし、ひな形をコピペするのだって、それをエディタやIDEのマクロでやるのであればある意味立派なメタプログラミングである。
しかし、メタプログラミングがどれくらい容易で、そしてどれくらい用いられているかは言語によって違う。コンパイルを前提とする静的言語よりも動的言語の方が容易だし、そして同じ動的言語でも、人が書いたメタプログラムをライブラリなどの形で利用することが多い言語もあれば、現場でも遠慮なくどしどし使う言語もある。Rubyは後者の最右翼ではなかろうか?
例えばオープンクラス。 JavaScript も Perl もクラスはオープン、つまり実行中にも動的に変更可能なのであるが、組み込みのクラスに現場で手を加えるのには抵抗がある。rubyismがいかんなく発揮されたprototype.jsに対する批判はほとんどそれに集約されるぐらいだし、魔術は独り占めするのではなくモジュールにしてCPANにうpすることが文化として根付いている Perl ですら、UNIVERSAL::
ネームスペースを改変するものには厳しい目が向けられる。
ところがRubyの文化においては、こういうコードを書くのは普通のようである。
class String def camelize gsub (/_(\w)/) { $1.upcase } end end puts 'get_element_by_id'.camelize
いわゆるモンキーパッチだ。
これを組み込みクラスの組み替えに慣れているはずの rubyists たちですら呆れるほどやったのが Ruby on Rails である。本書では第二部でこれを扱っている。いかに Rails がそれをやっているのか。そして自らがやりすぎるのを抑えているのか。
そう。やりすぎ。プログラミングが技術なら、メタプログラミングは魔術。覚えたの頃はつい使いすぎてしまう。しかし魔術だけあって、使いすぎれば自らを滅ぼす。しかも往々にして周りまで巻き添えにして。
def Object.const_missing(k) 42 end p LIFE p UNIVERSE p EVERYTHING
これに対するMatzの答えが素敵だ。
Rubyは君を信頼する。Rubyは君を分別のあるプログラマとして扱う。Rubyはメタプログラミングのような強力な力を与える。ただし、大いなる力には、大いなる責任が伴うことを忘れてはならない。
大人の世界へ、ようこそ。
Dan the Yet Another Metaprogrammer
追記:ちなみに lexical scope と dynamic scope の双方をサポートしているPerlでは、以下のようにしてモンキーパッチを局所化できる。
use v5.14; # strict, warnings, and say { package Bad; sub new { bless {}, shift }; sub broken{ "I'm broken" } } my $o = Bad->new; say $o->broken; { no warnings 'redefine'; local *Bad::broken = sub { "I'm fine" }; say $o->broken; } say $o->broken;
Rubyではどうやるのだろう。まあPerlでも滅多にこんなことやらないのだけど。
追^2記:内容が大人向けな分、翻訳が大人げないのもいい。「頭文字M」「絶望した!」「ジャッジメントですの」…
このブログにコメントするにはログインが必要です。
さんログアウト
この記事には許可ユーザしかコメントができません。