yield の便利さに気がつく

今更ながら、 Ruby の yield の便利さに気がつきました。きっかけは本で読んだコードだったのですが、私が自分で使ったのはこんなコード。

def if_found(obj)
  if obj.blank?
    render :text => "Not Found", :status => 404
  else
    yield if block_given?
  end
end

これを application.rb に仕込んでおいて、各種メソッドでこんな風に使います。

def show
  @item = Item.find(:first,
                    :conditions => ["id = ?", params[:id]])
  if_found(@item) do
    # 隣の Item オブジェクトを探すメソッド
    @next = @item.find_next
  end
end

block_given? を使っているため、ブロックなしで使う事も可能。

def show
  @item = Item.find(:first,
                    :conditions => ["id = ?", params[:id]])
  if_found(@item)
end

これなら @item が nil の場合は確実に 404 になり、動作を変更する場合も if_found メソッドを直せば済みます。
さらに、オブジェクトが画像のパスなどを持っている場合はこんな使い方もできます。

def download
  item = Item.find(:first,
                   :conditions => ["id = ?", params[:id]])
  if_found(item) do
    data = get_data_by_path(item.path)
    if_found(data) do
      send_data data.read
    end
  end
end

private
def get_data_by_path(path)
  begin
    open(path, "rb")
  rescue
    false
  end
end

これでオブジェクトそのものとパスの指定先、両方をチェックできます。
たぶん、使おうと思えば他にも色々と yield は使えるはず。要研究な分野です。