ようへいの日々精進XP

よかろうもん

2018 年 07 月 15 日 (日)

ジョギング

  • ゆるりと香椎浜 x 2 周
  • 暑さからか足の疲労感が半端ない

日課

  • 肩の周りに痛みがあったのでお休み

夕焼け

  • 奥さんと香椎浜
  • 缶ビールを片手に夕焼けを見たり, 馬鹿話で笑ったりした

今日のるびぃ ~ Ruby 技術者認定試験合格教本 (Silver/Gold 対応) Ruby 公式資格教科書 模擬試験 (5) オブジェクト指向系問題 (4) ~

irb に動作確認環境は以下の通り.

$ ruby --version
ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-linux]
$ irb --version
irb 0.9.6(09/06/30)

オブジェクト指向 (11)

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

class Root
  def m
    puts 'Root'
  end
end

class A < Root
  def m
    puts 'A'
  end
end

class B < A
  def m
    puts 'A'
  end
  undef m
end

B.new.m

以下, 解答.

例外発生 (NoMethodError が発生する)

以下, irb にて確認.

irb(main):001:0> class Root
irb(main):002:1>   def m
irb(main):003:2>     puts 'Root'
irb(main):004:2>   end
irb(main):005:1> end
=> :m
irb(main):006:0> 
irb(main):007:0* class A < Root
irb(main):008:1>   def m
irb(main):009:2>     puts 'A'
irb(main):010:2>   end
irb(main):011:1> end
=> :m
irb(main):012:0> 
irb(main):013:0* class B < A
irb(main):014:1>   def m
irb(main):015:2>     puts 'A'
irb(main):016:2>   end
irb(main):017:1>   undef m
irb(main):018:1> end
=> nil
irb(main):019:0> 
irb(main):020:0* B.new.m
NoMethodError: undefined method `m' for #<B:0x00557fddf364e0>
...

以下, 解説より抜粋.

  • m メソッドは, B クラスで undef されているので定義が取り消されている
  • B.new.m を実行すると NoMethodError が発生する

オブジェクト指向 (12)

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

module M1; end
module M2; end

class Cls1
  include M1
end

class Cls2 < Cls1
  def foo
    p self.ancestors
  end
  include M2
end

Cls2.new.foo

以下, 解答.

例外発生

以下, irb による確認.

irb(main):001:0> module M1; end
=> nil
irb(main):002:0> module M2; end
=> nil
irb(main):003:0> 
irb(main):004:0* class Cls1
irb(main):005:1>   include M1
irb(main):006:1> end
=> Cls1
irb(main):007:0> 
irb(main):008:0* class Cls2 < Cls1
irb(main):009:1>   def foo
irb(main):010:2>     p self.ancestors
irb(main):011:2>   end
irb(main):012:1>   include M2
irb(main):013:1> end
=> Cls2
irb(main):014:0> 
irb(main):015:0* Cls2.new.foo
NoMethodError: undefined method `ancestors' for #<Cls2:0x00564e49a66fd8>
...

以下, 解説より抜粋.

ちなみに, 以下のように書いても例外 (NameError) となる.

irb(main):016:0> class Cls2 < Cls1
irb(main):017:1>   def foo
irb(main):018:2>     p ancestors
irb(main):019:2>   end
irb(main):020:1> end
=> :foo
irb(main):021:0> Cls2.new.foo
NameError: undefined local variable or method `ancestors' for #<Cls2:0x00564e49a37990>

以下のように書くことで, ancestors の結果を得ることが出来る.

...
irb(main):022:0> class Cls2 < Cls1
irb(main):023:1>   def foo
irb(main):024:2>     p Cls2.ancestors
irb(main):025:2>   end
irb(main):026:1> end
=> :foo
irb(main):027:0> Cls2.new.foo
[Cls2, M2, Cls1, M1, Object, Kernel, BasicObject]
=> [Cls2, M2, Cls1, M1, Object, Kernel, BasicObject]

フムフム.