アペフチ

『メタプログラミングRuby 第2版』@Sendagaya.rb #134

Sendagaya.rb #134に参加して『メタプログラミングRuby』の読書会をして来た。今日は初参加、それも「最近Ruby始めたばかりで……」とか「プログラミングを始めたばかりで……」という人がすごく多かった。何があったんだろう?

先週に引き続き『メタプログラミングRuby 第2版』を読んだ。

「2.2.5 ネームスペースを使う」から15分みんなで黙読して、その後に気になることなどを話した。この「気になること」が盛り上がって、今日は他のことはしなかった。結構知らないことが書いてあって(第1版読んだはずなんだけど殆ど憶えてない……)面白い。

例えばコラムでloadに触れていた。普通loadは呼ぶ度にスクリプトが実行されるので、定数定義があると再定義の警告が表示されてしまう。ところが第二引数にtrueを渡して

load('defining-constants.rb', true)

と呼ぶと、この警告が避けられる。なぜかというと、「第二引数にtrueを渡すと、無名モジュールが作成され、スクリプトはその中で実行されるから」だと本では説明されている。「なるほどそうなのか、第二引数のこと知らなかった、勉強になったなあ」と、僕はあっさり流していたが、参加者から「無名モジュールってなんですか」っていう声が上がってそう言えば、知らないな、と思った。無名クラス(匿名クラス)はたまに使うのでそこからの類推と、文脈と合わせて勝手にイメージを作って納得していたが、知らない。ということで、デスクトップをプロジェクターで映していたfukajunさんがターミナルを出して、動かしてくれる。みんなで「こういうことかな」「じゃあこういう時はこうなるのかな」などと言っていると、それも全部実行してくれる。こうしてみんなで無名モジュール(anonymous module。僕は匿名モジュールと呼びたい)の理解を深めた。(翻訳の角さんから、無名、匿名についてこんなコメントを頂いた。https://twitter.com/kdmsnr/status/691839083266641920。うーんなるほど、勉強になる……。

その後Classのクラスは? Moduleのクラスは? Moduleのスーパークラスは? みたいな話が出ていて、Ruby始めたばかりの人がぴんとこないということだったのでその解説をしたりもした(tkawaさんが)。

prependは第1版にはなかったこともあってかなり盛り上がった。次の記事を見て老害がノスタルジーに浸りながらalias_method_chainの仕組みを解説したりもした。
Ruby2.0のModule#prependは如何にしてalias_method_chainを撲滅するのか!?

本に戻って、文中、prependに関して、こういう風に動作を説明してくれる。

module M1; end

module M2
  include M1
end

module M3
  prepend M1
  include M2
end

M3.ancestors # => [M1, M3, M2]

prependしたM1M3に差し込まれて、includeしたM2に置かれている。一度継承ツリーに入ったモジュールは二度は入らない。説明の通りだ。では、

module M3
  include M2
  prepend M1
end

と順番を変えたら、M3.ancestorsはどうなるだろうか。実行せずに答えられるだろうか? その答えに、どのくらい確信を持てるだろうか? これも、各々推測を述べた後、「fukajunターミナル」で実行して、回答を得たりした。

こういう、一人で本を読んでいるだけだと見逃しがちなことも、誰かが気付いて声を上げてくれるので読書会中々いいです。ただ(と言っても別に悪いとは思ってないけど)、このやり方は時間は掛かる。ので今日のSendagaya.rbはここで終わった。

次回は

なんかがいいですかねえ、って話をしていたけど、来週その場で決まることでしょう。

ちなみに、今回は開催前日にDoorkeeperのイベントが作成されたけど、次回分はその日のうちに作成されていたので、もう申し込める:
https://sendagayarb.doorkeeper.jp/events/38208