ブロックの受け渡し

以前マージソートを作ったとき、受け取ったブロックを別のメソッドへどう渡したらいいのか分からずに試行錯誤した。

プログラミング言語 Ruby

プログラミング言語 Ruby」を読んでいたら、もっとシンプルなブロックの渡し方が書いてあった。

module Enumerable
  def merge(o, &comp)
    comp = Proc.new{|a, b| a <=> b}  if comp.nil?
    i = 0
    j = 0
    m = []
    while i < size && j < o.size
      if comp [self[i], o[j]] <= 0
        m << self[i]
        i += 1
      else
        m << o[j]
        j += 1
      end
    end

    m += self[i..-1]
    m += o[j..-1]
  end

  def msort(&comp)
    return self  if size <= 1

    comp = Proc.new{|a, b| a <=> b}  if comp.nil?
    n = size / 2
    self[0...n].msort(&comp).merge(self[n..-1].msort(&comp), &comp)
  end

  def msort_by
    map{|i| [yield(i), i]}.msort{|a, b| a.first <=> b.first}.map{|i| i.last}
  end
end

ary = (0..15).to_a.map(&:to_s).shuffle
# => ["12", "13", "15", "14", "0", "3", "9", "10", "8", "4", "7", "2", "5", "6", "11", "1"]
ary.msort
# => ["0", "1", "10", "11", "12", "13", "14", "15", "2", "3", "4", "5", "6", "7", "8", "9"]
ary.msort{|a, b| a.to_i <=> b.to_i}
# => ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"]
ary.msort_by(&:to_i)
# => ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"]

["3f", "1e", "4d", "1c", "5b", "9a"].msort_by(&:to_i)
# => ["1e", "1c", "3f", "4d", "5b", "9a"]

msort でブロックを受け取った変数に & を付けて msort, merge に渡してやればよかったのか。