ようへいの日々精進XP

よかろうもん

2018 年 05 月 19 日(土)

ジョギング

  • 自宅 → 香椎宮香椎浜で 30 分くらい
  • ペースはそこまで速くないのに, とてもキツイ...

日課

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

お味噌

  • 奥さんが手作り味噌教室で味噌をこねてきた
  • この教室で作るお味噌はとても美味しくてお気に入り
  • 出来上がりが楽しみ

手羽と大根の煮込み

  • 夕飯に奥さんが煮込んでくれた
  • 日本酒のお供にサイコーだった

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

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)

Proc (ブロック引数)

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

def foo(&block, *args)
  block.call(*args)
end

foo('a', 'b', 'c') do |*args|
  p args.include?('d') ? "hello" : args
end

例外 (SyntaxError) が発生する

以下, irb による確認.

irb(main):001:0> def foo(&block, *args)
irb(main):002:1>   block.call(*args)
irb(main):003:1> end
SyntaxError: (irb):1: syntax error, unexpected ',', expecting ')'
def foo(&block, *args)
               ^
(irb):3: syntax error, unexpected keyword_end, expecting end-of-input

以下, 解説より抜粋.

  • ブロック引数は仮引数の最後に記述する
def foo(*args, &block)
...

以下, 改めて irb による確認.

irb(main):001:0> def foo(*args, &block)
irb(main):002:1>   block.call(*args)
irb(main):003:1> end
=> :foo
irb(main):004:0> 
irb(main):005:0* foo('a', 'b', 'c') do |*args|
irb(main):006:1*   p args.include?('d') ? "hello" : args
irb(main):007:1> end
["a", "b", "c"]
=> ["a", "b", "c"]

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.my_method

Cls1#method_missing

以下, irb による確認.

irb(main):021:0> 
irb(main):022:0* Cls2.new.my_method
Cls1#method_missing
=> nil

以下, 解説より抜粋.

  • method_missing は, 継承チェーンを辿った末に呼び出したメソッドが見つからなかった場合に呼び出される
  • Cls2 において class << self; end で定義されたメソッドは, 特異クラスのメソッドとなる為, 設問の Cls2.new.my_method を呼び出すと A#method_missing が出力される

以下は, Cls2 の特異クラスのメソッド, Cls1インスタンスメソッドを呼びだそうとした場合.

irb(main):023:0> Cls2.my_method
Cls2.method_missing
=> nil
irb(main):024:0> Cls1.new.my_method
Cls1#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 になる.
irb(main):001:0> class Cls
irb(main):002:1>   public
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

ヘエ~

ちなみに, private メソッドを確認する場合には, private_methods メソッドで確認する.

irb(main):010:0> Cls.new.private_methods.grep(/init/)
=> [:initialize, :initialize_copy, :initialize_dup, :initialize_clone]

フムフム.