Rubyでブロックとメソッドをコールバック処理として実行する

前回作ったHello Rubyの処理

前回、Hello Rubyで作った処理をせっかくなので、勉強がてらクラス構文で定義してみる事にした。
ついでに、ブロック、メソッドそれぞれを利用したコールバック処理をできるようにしてみた。

まずは前回作ったやつを少し直したのがこれ。

(変更前)combination.rb
R = 9

numbers = (1..100).to_a

# 組み合わせを列挙しながらtestメソッドを実行
def test(*combinations) # *を頭に付けると引数が可変長配列になるらしい
  p combinations
end

numbers.repeated_combination(R) { |*combination| test(combination) }

今風?のコールバックの基本は、どうやら、呼び出し側で、

hoge(){ |ret| #blk処理 }

としておいて、hoge()内では、

yield

と実装してコールバックするのがシンプルでいいらしい。
とは言え、メソッドをそのままコールバックとしたい事もあろうかと思い、その方法もやってみた。

ブロックとメソッドをコールバックとしてするよう作り直した結果

(変更後)combination.rb
R = 3

class Combinations
  # ブロックをコールバックとして実行するメソッド
#これでもイケる
#  def findWithBlk(ary, r, &blk)
  def findWithBlk(ary, r)
    #yieldでコールバック実行
#これでもイケる
#    ary.repeated_combination(r) { |*combination| blk.call(combination) } 
    ary.repeated_combination(r) { |*combination| yield(combination) }
  end

  # メソッドをコールバックとして実行するメソッド
  def findWithMethod(ary, r, method)
    #与えられたメソッドを.call()でコールバック実行
    ary.repeated_combination(r) { |*combination| method.call(combination) }
  end

  #強引にブロックとメソッドで両方コールバック実行するメソッド
  def find(ary, r, method=nil)
    #ラムダの無名関数
    callback = lambda{|method, combination|
      if block_given?
        yield(combination)
      elsif method !=nil
        method.call(combination)
      end
    }
    ary.repeated_combination(r) { |*combination| callback.call(method, combination) }
  end
end



numbers = (1..100).to_a

# ブロックをコールバックとして実行
cmb = Combinations.new
cmb.findWithBlk(numbers, R) { |*combination| p combination }

# #メソッドをコールバックとして実行
def callback(*combination)
  p combination
end
cmb.findWithMethod(numbers, R, method(:callback))

#試しに、強引にブロックとメソッドで両方コールバック実行してみる
cmb.find(numbers, R, method(:callback))
cmb.find(numbers, R) { |*combination| p combination }

ところで、ブロックとメソッドは何が違うんだ?
どういう性質で、どう使い分けるとか、そこら辺も調べていきたい。
オーバーロードがRubyには無いんだろうか。クラスのメソッド名を同じにしたらエラーが出た。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.