ようへいの日々精進XP

よかろうもん

2018 年 08 月 02 日 (木)

ジョギング

  • 香椎浜 x 2 周
  • 引き続き, なんかギクシャクしている感じ
  • 右足の太もも裏, お尻にかけて痛み

日課

  • お休み

JAWS-UG のあつまり

  • 当初の目的からは逸脱してしまったが, 色々と話せて楽しかった
  • そして, 藤崎さんが用意してくれたお店がとてもマグロの美味しいお店で, 次回は奥さんをつれて行こうと思う

今日のるびぃ ~ 先人達の知恵と教訓 (1) ~

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

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

今回は, こちら に記載されていた, 例題を解いてみる. また, こちらの記事についても参考にさせて頂いた.

問題 (1)

module M
  def method_missing(id, *args)
    puts "M#method_missing()"
  end
end

class A
  include M
  def method_missing(id, *args)
    puts "A#method_missing()"
  end
end

class B < A
  def method_x
    puts "#{self.class.name}:method_x"
  end
  class << self
    def method_missing(id, *args)
      puts "B`method_missing()"
    end
  end
end

obj = B.new
obj.method_x
obj.method_y

以下, 解答予想.

B:method_x
A#method_missing()

以下, irb にて確認.

irb(main):025:0* obj = B.new
=> #<B:0x0055cd982f1e38>
irb(main):026:0> obj.method_x
B:method_x
=> nil
irb(main):027:0> obj.method_y
A#method_missing()
=> nil

以下, 解説.

  • obj.method_x で素直に B#method_x が呼ばれる
  • obj.method_y は, 継承を辿って super クラス (class A) の method_missing が呼ばれる

問題 (2)

class Module
  def method_missing(id, *args)
    puts "Module#method_missing()"
  end
end

class Class
  def method_missing(id, *args)
    puts "Class#method_missing()"
  end
end

module M
  def method_missing(id, *args)
    puts "M#method_missing()"
  end
end

class A
  include M
  def method_missing(id, *args)
    puts "A#method_missing()"
  end
end

class B < A
  def self.method_x
    puts "#{self}.method_x"
  end
  def method_missing(id, *args)
    puts "B#method_missing()"
  end
end

B.method_x
B.method_y

以下, 解答予想.

B.method_x
Class#method_missing

以下, irb にて確認.

... 略 ...
irb(main):034:0> 
irb(main):035:0* B.method_x
B.method_x
=> nil
irb(main):036:0> B.method_y
Class#method_missing()
=> nil

以下, 解説.

  • B クラスの self.method_x で, クラスメソッド B.method_x が出力される
  • B クラスにはクラスメソッド method_y は未定義なので, Class クラスの method_missing が呼ばれて Class#method_missing() が出力される

問題 (3)

class Module
  def const_missing(id)
    puts "Module#const_missing()"
    id = 1
  end
end

class Class
  def const_missing(id)
    puts "Class#const_missing()"
    id = 2
  end
end

class Object
  def const_missing(id)
    puts "Object#const_missing()"
    id = 3
  end
end

class A
  def const_missing(id)
    puts "A#const_missing()"
    id = 4
  end
end

class B < A
  CNST_X = "123"
    
  def method01
    puts "CNST_X=#{CNST_X}"
    puts "CNST_Y=#{CNST_Y}"
  end

  def const_missing(id)
    puts "B#const_missing()"
    id = 5
  end
end

obj = B.new
obj.method01

以下, 解答予想.

CNST_X=123
Class#const_missing()
CNST_Y=2

以下, irb にて確認.

irb(main):043:0* obj = B.new
=> #<B:0x0055f9bd413860>
irb(main):044:0> obj.method01
CNST_X=123
Class#const_missing()
CNST_Y=2
=> nil

以下, 解説.

以下, も少し const_missing について.

class Class
  def const_missing(const)
    const = '0'
  end
end

class Cls1
  def const_missing(const)
    const = '1'
  end
end

class Cls2 < Cls1
  CONST_1 = '123'
  def method1
    puts CONST_1
    puts CONST_2
  end
end

Cls2.new.method1

以下, irb にて確認.

... 略 ...
irb(main):020:0> Cls2.ancestors
=> [Cls2, Cls1, Object, Kernel, BasicObject]
irb(main):021:0> Cls2.new.method1
123
0
=> nil

以下, Object クラスと Class クラスで const_missing を定義した場合.

class Object
  def self.const_missing(const)
    const = '-1'
  end
end

class Class
  def const_missing(const)
    const = '0'
  end
end

class Cls1
  def const_missing(const)
    const = '1'
  end
end

class Cls2 < Cls1
  CONST_1 = '123'
  def method1
    puts CONST_1
    puts CONST_2
  end
end

Cls2.new.method1

以下, irb にて確認.

... 略 ...
irb(main):025:0> Cls2.ancestors
=> [Cls2, Cls1, Object, Kernel, BasicObject]
irb(main):026:0> 
irb(main):027:0* Cls2.new.method1
123
-1
=> nil

以下, メモ.

  • const_missing はクラスメソッドで実装されている必要がある
  • Class クラスのインスタンスメソッドは他のクラスのクラスメソッドとして処理される

フムフム.