ローカル変数をスコープ内側へ
Perlだとこれは動く。
my $outer = 123; sub hoge { print "$outer\n"; } hoge(); #=> 123
Perlは内側への変数スコープは有効だからだ。
対してRubyは動かない。
outer = 123 def hoge puts outer end hoge() #=> NameError: undefined local variable or method `outer' for main:Object
最初はこれに驚いた。
いまメタプログラミングRubyを読んでいるのだけれど、ここに詳しく書かれていた。
スコープゲート
プログラムがスコープを切り替えて、新しいスコープをオープンする場所は3つある。
・クラス定義
・モジュール定義
・メソッド呼び出し
クラスやモジュールの定義、あるいはメソッドに出入りすると、スコープは変化する。この3つの境界線は、class、module、defといったキーワードで印がつけられている。3つのキーワードはそれぞれスコープゲートのように振る舞う。
(P.115)
上記の例だと、defでスコープがouter変数のいるスコープから切り替わるため、def hoge内でアクセスできない仕様ということらしい。
で、だがしかし、とは言うものの、外側の変数を簡単に参照したい場合もある。
(一番簡単なのはグローバル変数を使うことだろう。)
メタプログラミングRubyでは、スコープが切り替わらない、「ブロック」を利用して外側の変数を参照している例が載っていた。
ブロックは、ブロックが作成された時点での変数スコープが有効になるので、それを利用している。これはすごいなーと思った。
outer = 123 # トップレベルでdefine_methodを呼び出す Kernel.send :define_method, :hoge do puts outer end hoge() #=> 123
よくできてるなー。
- 作者: Paolo Perrotta,角征典
- 出版社/メーカー: KADOKAWA/アスキー・メディアワークス
- 発売日: 2010/08/28
- メディア: 大型本
- 購入: 18人 クリック: 533回
- この商品を含むブログ (125件) を見る