メタプログラミングRuby 第1章 月曜日:オブジェクトモデル その2

急遽朝の読書時間にやることができてしまってしばらくお休みしていました。無事終わったので朝の一人読書会を再開します。
しかし再開そうそう電車の遅れで短縮です。第1章の定数のところからでした

  • 定数とネームスペース
    • Module(Class)がネームスペースとしての役割も持っていて定数はネストできる
  • Module#constants でそのモジュール内の定数一覧が取れるのは知ってましたが Module.constants でトップレベルの定数一覧が取れるのは知りませんでした。Object.constants を使ってました。同じものがかえってくるみたいですけど。
Module.constants == Object.constants # => true
  • Module.nesting で現在のレキシカルなスコープが取れる
  • コラム「定数ツリーの枝刈り」では Kernel#load の第2引数に true を渡すと無名モジュールを作ってその中で評価する(定数やメソッド定義が捨てられる)というのが紹介されていましたが、load するスクリプトで次のように定数を絶対パスで参照されていたらやはりだめですね。
::Const = 100
class ::String
  # String のメソッドを再定義して壊してしまう
  def size
    0
  endend
  • 1.4 で定数の衝突(Class と Module を同じ名前で定義してた)のケースが紹介されていますが、Ruby はネームスペースについての機能が弱いですね。本文でもどちらも Class だったらすぐに衝突に気がつかなかったかもしれない → ユニットテスト重要と書いてありますが、つまりユニットテストで問題がなければ衝突してても(意図せず同じクラスを別の用途で使い回していても)気にしない、という文化ということでしょうか。しかしさらにメタプログラミングでそこを弄ろうとすると問題が発生するので、そういう潜在的な問題(衝突)も検出したいところです。

今日はほぼ定数のところだけでした。オブジェクトモデルはさらに継承と特異クラスのツリーとメソッド探索のところが残っているようなのでまだ第1章は続きます。