ジョギング
- 香椎浜 x 2 周 29 分くらい
- ペースが速かったかな...
日課
- (腕立て x 50 + 腹筋 x 50) x 3
風が通り抜ける場所で
- 終日仕事をしていた
- だいぶん涼しかった
今日のるびぃ ~ REx - Ruby Examination にチャレンジ (40) ~
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)
Module.nesting
以下のコードを実行するとどうなるか.
module SuperMod end module SuperMod::BaseMod p Module.nesting end
以下, 解答.
[SuperMod::BaseMod]
以下, irb にて確認.
irb(main):001:0> module SuperMod irb(main):002:1> end => nil irb(main):003:0> irb(main):004:0* module SuperMod::BaseMod irb(main):005:1> p Module.nesting irb(main):006:1> end [SuperMod::BaseMod] => [SuperMod::BaseMod]
以下, 解説より抜粋.
Module.nesting
はモジュールやクラスのネストの状態を表示する- モジュールがネストされている場合, ネストの全ての状態を表示する
- インデントして別々に書いた場合 (
module SuperMod;module BaseMod; p Module.nesting; end ;end
) に比べて, プレフィックス (SuperMod::BaseMod
) がある場合は内側にあるモジュールしかネストの状態は表示されない
irb(main):001:0> module SuperMod irb(main):002:1> p Module.nesting irb(main):003:1> end [SuperMod] => [SuperMod] irb(main):004:0> irb(main):005:0* module SuperMod irb(main):006:1> module BaseMod irb(main):007:2> p Module.nesting irb(main):008:2> end irb(main):009:1> end [SuperMod::BaseMod, SuperMod] => [SuperMod::BaseMod, SuperMod] irb(main):010:0> irb(main):011:0* module SuperMod::BaseMod irb(main):012:1> p Module.nesting irb(main):013:1> end [SuperMod::BaseMod] => [SuperMod::BaseMod]
変態的な定数参照
以下のコードを実行するとどうなるか.
class Ca CONST = "001" end class Cb CONST = "010" end class Cc CONST = "011" end class Cd CONST = "100" end module M1 class C0 < Ca class C1 < Cc class C2 < Cd p CONST class C2 < Cb end end end end end
以下, 解答.
100 が表示される
以下, 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 "100" => nil
以下, 解説より抜粋.
レキシカルスコープとは...
- 変数を参照する仕様の一つ (ダイナミックスコープというのもある)
- 他の関数のローカル変数は参照することが出来ない
- 設問でのレキシカルスコープとは,
module M1 ~ end
までになるんだと思う
以下, 設問を利用して実験.
class Ca CONST = '001' end class Cb CONST = '002' end module M1 class C0 < Ca class C1 < Cb p CONST end end end
これを実行すると, 以下のように 002
が出力される.
... 略 ... irb(main):008:0> irb(main):009:0* module M1 irb(main):010:1> class C0 < Ca irb(main):011:2> class C1 < Cb irb(main):012:3> p CONST irb(main):013:3> end irb(main):014:2> end irb(main):015:1> end "002" => "002"
では, 以下のように定数 CONST
を定義した場合にどうなるか.
... 略 ... module M1 class C0 < Ca CONST = 'aaaaaaaaaaaaaa' class C1 < Cb p CONST end end end
以下のように aaaaaaaaaaaaaa
と出力される.
irb(main):016:0> module M1 irb(main):017:1> class C0 < Ca irb(main):018:2> CONST = 'aaaaaaaaaaaaaa' irb(main):019:2> class C1 < Cb irb(main):020:3> p CONST irb(main):021:3> end irb(main):022:2> end irb(main):023:1> end "aaaaaaaaaaaaaa" => "aaaaaaaaaaaaaa"
これは, レキシカルスコープ内に定数が定義されていると言える. 対して, 以下のように定義した場合にどうなるか.
... 略 ... CONST = 'aaaaaaaaaaaaaa' module M1 class C0 < Ca class C1 < Cb p CONST end end end
以下のように 002
と表示される.
... 略 ... irb(main):008:0> CONST = 'aaaaaaaaaaaaaa' => "aaaaaaaaaaaaaa" irb(main):009:0> module M1 irb(main):010:1> class C0 < Ca irb(main):011:2> class C1 < Cb irb(main):012:3> p CONST irb(main):013:3> end irb(main):014:2> end irb(main):015:1> end "002" => "002"
これは, 定数がレキシカルスコープに無い為, スーパークラスを探索して定数を参照している.
フムフム.