for in else end 的な話

以下の記事を読みました。

2008-09-09 for in else end

私は Ruby の for 構文は全く使いません。なので for in else end みたいなのが増えてもきっと使わないと思います。だけど記事にあるような場面ってしばしばありますよね。というわけで代替策を考えてみました。

まず高尾さんが挙げた例を引用します。

<ol>
<%- sample_programs = SampleProgram.find(:all, :order => "updated_at") -%>
<%- if sample_programs.length > 0 -%>
  <%- for sp in sample_programs -%>
  <li><%= h(sp.title) %></li>
  <%- end -%>
<%- else -%>
  <li>サンプルプログラムが登録されていません。</li>
<%- end -%>
</ol>

if と for が一緒になってればいい、のかな? では SampleProgram.find は常に配列を返すことを前提として以下のように書いてはどうでしょうか。

require "erb"

sample = []

puts ERB.new(<<__CODE__, nil, "-").result
<ol>
<%- if for sp in sample -%>
  <li><%= sp %></li>
<%- end.empty? then -%>
  <li>サンプルプログラムが登録されていません。</li>
<%- end -%>
</ol>
__CODE__

この結果は次のようになります。

<ol>
  <li>サンプルプログラムが登録されていません。</li>
</ol>

やったね!...と思ってくれる人はひょっとして少ないでしょうか?

しかしですよ、どうせ世の中 rails が流行っているらしいので、猿っぽい汚らわしい拡張を行なってもバチは当たらないのではないかと思うわけです。

require "erb"

sample = []

class Array
  def else(&block)
    block.call if empty?
  end
end

puts ERB.new(<<__CODE__, nil, "-").result
<ol>
<%- for sp in sample -%>
  <li><%= sp %></li>
<%- end.else do -%>
  <li>サンプルプログラムが登録されていません。</li>
<%- end -%>
</ol>
__CODE__

いかがでしょうか。私なら、他人がこんな猿なコード書いているのを見たら、蹴飛ばすと思います。