ようへいの日々精進XP

よかろうもん

2018 年 06 月 17 日 (日)

ジョギング

  • 自宅→香椎神宮香椎浜 で 35 分くらい
  • 臀部の強い張り (ストレッチでなんとかしている)

日課

  • (腕立て x 50 + 腹筋 x 50) x 3

引き続き

  • 仕事をしつつ, 昨日よりは少しのんびり過ごすことが出来た
  • どこにも連れて行ってあげられなかったので, 奥さんには申し訳ないと思っている

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

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)

method_missing

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

module Mod
  def method_missing(id, *args)
    puts "Mod#method_missing"
  end
end
class Cls1
  include Mod
  def method_missing(id, *args)
    puts "Cls1#method_missing"
  end
end
class Cls2 < Cls1
  class << self
    def method_missing(id, *args)
      puts "Cls2.method_missing"
    end
  end
end

Cls2.new.dummy_method

Cls1#method_missing

以下, irb にて確認.

irb(main):001:0> module Mod
irb(main):002:1>   def method_missing(id, *args)
irb(main):003:2>     puts "Mod#method_missing"
irb(main):004:2>   end
irb(main):005:1> end
=> :method_missing
irb(main):006:0> class Cls1
irb(main):007:1>   include Mod
irb(main):008:1>   def method_missing(id, *args)
irb(main):009:2>     puts "Cls1#method_missing"
irb(main):010:2>   end
irb(main):011:1> end
=> :method_missing
irb(main):012:0> class Cls2 < Cls1
irb(main):013:1>   class << self
irb(main):014:2>     def method_missing(id, *args)
irb(main):015:3>       puts "Cls2.method_missing"
irb(main):016:3>     end
irb(main):017:2>   end
irb(main):018:1> end
=> :method_missing
irb(main):019:0> 
irb(main):020:0* Cls2.new.dummy_method
Cls1#method_missing
=> nil

以下, 解説より抜粋.

  • method_missing は, 継承チェーンを辿った末にメソッドが見つからなかった時に呼び出される
  • method_missing も継承チェーンを辿る
  • class << self; end で定義されたメソッドは, 特異クラスのインスタンスメソッドになる為, 設問コードでは呼び出すことが出来ない

以下のように呼び出すことで, Cls2 特異メソッドの method_missing を呼び出すことが出来る.

irb(main):021:0> Cls2.dummy_method
Cls2.method_missing
=> nil

メソッドの可視性

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

class Cls
private
  def initialize
  end
end

p Cls.new.public_methods.include? :initialize

false が出力される.

以下, irb にて確認.

irb(main):001:0> class Cls
irb(main):002:1> private
irb(main):003:1>   def initialize
irb(main):004:2>   end
irb(main):005:1> end
=> :initialize
irb(main):006:0> 
irb(main):007:0* p Cls.new.public_methods.include? :initialize
false
=> false

以下, 解説より抜粋.

  • initialize の可視性はprivateに設定されている
  • initialize の可視性を public に設定したとしても, 必ず private となる

Object#private_methods というメソッドも用意されている.

irb(main):001:0> class Cls
irb(main):002:1>   def initialize
irb(main):003:2>   end
irb(main):004:1> end
=> :initialize
irb(main):005:0> Cls.new.private_methods(false)
=> [:initialize]
irb(main):006:0> Cls.new.private_methods(false).include?(:initialize)
=> true

Object#private_methods の引数に false を渡すと, スーパークラスに定義されているメソッドを除いて出力される.

フムフム.