クラスの拡張時にsuperでブロックを渡す

こんな感じの短いブロックを使った処理を毎回書いてるなって時ないでしょうか。

uniq_arr = arr.uniq{ |item| item[:name] }

メソッドに分離してもいいんですが、

def name_uniq arr
  arr.uniq{ |item| item[:name] }
end

name_uniq arr

メソッドに分離すると順番が逆になって読みにくくなるんですよね、

そんな時はこんな拡張はどうでしょう。superにもブロックが渡せるんですね。Procを引数として渡してるだけなので当たり前か。

class ExtendedArray < Array
  def uniq
    super do |item|
      item[:name]
    end
  end
end

arr = ExtendedArray.new

arr << {usr_id: 1, name: "Woods"}
arr << {usr_id: 2, name: "Rhodes"}
arr << {usr_id: 3, name: "Woods"}

p arr
# [{:usr_id=>1, :name=>"Woods"}, {:usr_id=>2, :name=>"Rhodes"}, {:usr_id=>3, :name=>"Woods"}]

p arr.uniq
# [{:usr_id=>1, :name=>"Woods"}, {:usr_id=>2, :name=>"Rhodes"}]

 

キーだけ変える可能性がある場合は、一旦元のメソッドを退避させてから呼び出します。

class ExtendedArray < Array
  alias_method :origin_uniq, :uniq
  def uniq(key)
    origin_uniq do |item|
      item[key]
    end
  end
end

arr = ExtendedArray.new

arr << {user_id: 1, name: "Woods"}
arr << {user_id: 1, name: "Rhodes"}
arr << {user_id: 3, name: "Woods"}

p arr
# [{:user_id=>1, :name=>"Woods"}, {:user_id=>1, :name=>"Rhodes"}, {:user_id=>3, :name=>"Woods"}]

p arr.uniq(:name)
# [{:user_id=>1, :name=>"Woods"}, {:user_id=>1, :name=>"Rhodes"}]

p arr.uniq(:user_id)
# [{:user_id=>1, :name=>"Woods"}, {:user_id=>3, :name=>"Woods"}]