メタプログラミング入門(2) ネストしたスコープ
Ruby では,一般的な手続き型言語と違いスコープがネストしません.
var1 = 0 class Hoge # var1 は見えない var2 = 1 def huga # var1 も var2 も見えない end end
class 内で共有できる変数としてインスタンス変数がありますが,特定のメソッドだけ共有したいなどの要求に答えることはできません.
グローバルスコープについてはグローバル変数がありますが,こちらも細かくスコープを操る事ができません.また,トップレベルオブジェクト(=main)でのインスタンス変数は,self=main のときしか使えないのでクラス定義内では使えないのでこれも微妙です.
解決方法としては,class の代わりに Class.new を,def の代わりに Module#define_method を使います.
このとき与えるブロックは宣言したスコープで束縛されている変数を取り込むので,ネストした変数スコープを実現できます.
var1 = 0 # class の代わりに使う Hoge = Class.new do var1 # => 0 var1 は見える var2 = 1 # def の代わりに使う define_method :huga do var1 # => 0 var1 は見える var2 # => 1 var2 は見える end # var2 を共有したくないメソッド def piyo var1 # => 0 var1 は見える # var2 は見えない end end