天気
- 小雨からの曇
- 梅雨入り
ジョギング
日課
- (腕立て x 50 + 腹筋 x 50) x 3
夕飯
- 手羽中の磯辺揚げ風
- ピーマンと新玉ねぎの天ぷらっぽいやつ
今日のるびぃ ~ REx - Ruby Examination にチャレンジ (11) ~
REx - Ruby Examination の問題を自分なりにアレンジした上で 1 〜 3 問くらいずつ解いていく. 正直言ってかなり難しい. 尚, irb に動作確認環境は以下の通り.
$ ruby --version ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-linux] $ irb --version irb 0.9.6(09/06/30)
mix-in
以下のコードを実行するとどうなるか.
module Mod1 end module Mod1::Mod2 p Module.nesting end
Mod1::Mod2
以下, irb による動作確認.
irb(main):001:0> module Mod1 irb(main):002:1> end => nil irb(main):003:0> irb(main):004:0* module Mod1::Mod2 irb(main):005:1> p Module.nesting irb(main):006:1> end [Mod1::Mod2] => [Mod1::Mod2]
以下, 解説より抜粋.
Module.nesting
はネストの状態を表示する- モジュールがネストされている場合には, ネストの状態をすべて表示する
Mod1::Mod2
のようにプログラムを書くとモジュールMod1
の内側にモジュールMod2
があることを表現することが出来る- インデントして個別に書いた場合と比較して, プレフィックス (
::
) がある場合は内側にあるモジュールしかネストの状態は表示されない
irb(main):001:0> module Mod1 irb(main):002:1> p Module.nesting irb(main):003:1> end [Mod1] => [Mod1] irb(main):004:0> module Mod1::Mod2 irb(main):005:1> p Module.nesting irb(main):006:1> end [Mod1::Mod2] => [Mod1::Mod2] irb(main):007:0> module Mod1 irb(main):008:1> module Mod2 irb(main):009:2> p Module.nesting irb(main):010:2> end irb(main):011:1> end [Mod1::Mod2, Mod1] => [Mod1::Mod2, Mod1] irb(main):012:0> irb(main):012:0> module Foo irb(main):013:1> module Bar irb(main):014:2> module Baz irb(main):015:3> p Module.nesting irb(main):016:3> end irb(main):017:2> end irb(main):018:1> end [Foo::Bar::Baz, Foo::Bar, Foo] => [Foo::Bar::Baz, Foo::Bar, Foo irb(main):019:0> class Cls1 irb(main):020:1> class Cls2 irb(main):021:2> class Cls3 irb(main):022:3> Module.nesting irb(main):023:3> end irb(main):024:2> end irb(main):025:1> end => [Cls1::Cls2::Cls3, Cls1::Cls2, Cls1
尚, Module.nesting
はモジュールだけでなく, クラスについても同様にメソッドを呼び出した時点のネスト情報を配列に入れて返す.
定数
以下のプログラムを実行するとどうなるか.
class Ca CONST = "A" end class Cb CONST = "B" end class Cc CONST = "C" end class Cd CONST = "D" end module M1 class C0 < Ca class C1 < Cc class C2 < Cd p CONST class C2 < Cb end end end end end
D が出力される
以下, irb で確認.
... 略 irb(main):017:0* module M1 irb(main):018:1> class C0 < Ca irb(main):019:2> class C1 < Cc irb(main):020:3> class C2 < Cd irb(main):021:4> p CONST irb(main):022:4> irb(main):023:4* class C2 < Cb irb(main):024:5> end irb(main):025:4> end irb(main):026:3> end irb(main):027:2> end irb(main):028:1> end "D" => nil
以下, 解説より抜粋.
- Rubyは定数参照はレキシカル (≒静的に) に決定されるが, 設問ではレキシカルスコープに定数は定義されていない
- レキシカルスコープに定数がない場合は, スーパークラスの探索を行う
- 設問では, クラス
C2
のスコープで定数を参照する - クラス
C2
のスーパークラスはクラスCd
となるので, "D" が正解となる
レキシカル又は,レキシカルスコープについては, フワッとしか認識しかないので機会があれば掘り下げたい. 今のところは, スコープ外の同名変数に影響を与えないというくらいのフワッとした認識しかない...
フムフム.