著作一覧 |
ちょっとしたことで、rownumを使うかrowidを使うかで議論になって、結局はrownum派の勘違いで実はrowidを使うべきという結論となった。
というのは、どうでも良いのだが、その過程でrownumについて、OracleがOTNのそこかしこで、where rownum > 1というのを書くなという注釈を入れまくっていることに気づいて、ちょっと不思議になった。
rownumというのは、Oracleの場合、フェッチしてきたロウに振られる1からの連番で擬似カラムということになる。
rubyの、each_with_indexみたいなものだ。
で、とにかくそこら中に「where rownum > 1」は間違いだからそう書きたければこう書けという注釈を入れている。そういうコラムまである。
そんなにいっぱい注釈が必要なくらい、みんながみんな間違えるということを知っているのなら、なぜ振る舞いを直さないのか? と、とても不思議になる。
それはそれとして、そのバグはおもしろい。
同じことをrubyでできないか考えてみる。
Rubyでリストのフェッチ時にフィルタを入れるには、Enumerable#selectを使うことになるから、ここではselect_with_indexというメソッドを考えることにする。
かつ、以下のように振舞う必要がある。
a = [1, 2, 3, 4].select_with_index do |e, i| i > 1 end p a #=> []したがって、次のようには実装できない。
module Enumerable def select_with_index ret = [] self.each_with_index do |e, i| if yield(e, i + 1) # +1は不要かも 0オリジンでいいよな ret << e end end ret end end
これをOracleのrownumと同様にするには、以下のようにすれば良いのか。
module Enumerable def select_with_index # oracle's rownum type ret = [] self.each do |e| if yield(e, ret.size + 1) # +1は不要かも 0オリジンでいいよな ret << e end end ret end end
簡単に実装できるが、何の役に立つかな?
ジェズイットを見習え |