ブロックの受け渡し
以前マージソートを作ったとき、受け取ったブロックを別のメソッドへどう渡したらいいのか分からずに試行錯誤した。
「プログラミング言語 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 に渡してやればよかったのか。