ようへいの日々精進XP

よかろうもん

2018 年 06 月 29 日 (金)

ジョギング

  • 香椎浜 x 2 周 30 分くらい
  • お昼休みに

日課

  • おやすみ

ソフトウェアテスト勉強会

fusic.connpass.com

に参加した. ワークショップを絡めて体系的にソフトウェアテストの基礎を学ぶことができた.

今日のるびぃ ~ REx - Ruby Examination にチャレンジ (41) ~

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_eval

以下のコードを実行するとどうなるか.

module A
  B = 42

  def f
    21
  end
end

A.module_eval do
  def self.f
    p B
  end
end

B = 15

A.f

以下, 解答.

15 が表示される.

以下, irb にて確認.

irb(main):001:0> module A
irb(main):002:1>   B = 42
irb(main):003:1> 
irb(main):004:1*   def f
irb(main):005:2>     21
irb(main):006:2>   end
irb(main):007:1> end
=> :f
irb(main):008:0> 
irb(main):009:0* A.module_eval do
irb(main):010:1*   def self.f
irb(main):011:2>     p B
irb(main):012:2>   end
irb(main):013:1> end
=> :f
irb(main):014:0> 
irb(main):015:0* B = 15
=> 15
irb(main):016:0> 
irb(main):017:0* A.f
15
=> 15

以下, 解説より抜粋.

  • module_eval にブロックを渡した場合のネストの状態を確認
irb(main):018:0> A.module_eval do
irb(main):019:1*   Module.nesting
irb(main):020:1> end
=> []

ブロックで渡した場合には, トップレベルで定義されたことになっている. ちなみに, 文字列として渡した場合のネストの状態は以下の通り.

irb(main):021:0> A.module_eval <<-EOT
irb(main):022:0"   Module.nesting
irb(main):023:0" EOT
=> [A]

文字列として渡された場合には, 定義したモジュール内に定義されている.

  • トップレベルで定数を定義した場合には, Object クラスの定数となる
irb(main):001:0> B = "foo"
=> "foo"
irb(main):002:0> Object.const_get(:B)
=> "foo"

設問では, トップレベルで定義された定数を探索する為, 15 となる. ちなみに, 以下のようなコードだった場合にどうなるか.

module A
  B = 42

  def f
    21
  end
end

A.module_eval <<-EOT
  def self.f
    p B
  end
EOT

B = 15

A.f

以下, 解答.

42 が表示される.

以下, irb による確認.

irb(main):001:0> module A
irb(main):002:1>   B = 42
irb(main):003:1> 
irb(main):004:1*   def f
irb(main):005:2>     21
irb(main):006:2>   end
irb(main):007:1> end
=> :f
irb(main):008:0> 
irb(main):009:0* A.module_eval <<-EOT
irb(main):010:0"   def self.f
irb(main):011:0"     p B
irb(main):012:0"   end
irb(main):013:0" EOT
=> :f
irb(main):014:0> 
irb(main):015:0* B = 15
=> 15
irb(main):016:0> 
irb(main):017:0* A.f
42
=> 42

フムフム.