In article <1053418411.495451.20782.nullmailer / picachu.netlab.jp>, matz / ruby-lang.org (Yukihiro Matsumoto) writes: > 要するに > > * <=>が成立しないケースは厳密には2種類ある > + そもそも型が合わない > + 型は合うが順序関係が成立しない > * これらを区別するため、前者は例外、後者はnilになるべきだ。 > > ということですよね。 はい。 > 私の考えとしては > > * 2種類を区別する必要があるのか > > ほとんどの場合、ユーザが関心あるのは、比較できるかできな > いかだけ。 同意できません。ほとんどの場合、ユーザは比較できるときのことしか関心を 持たないように思います。 したがって、比較できないときに対処するコードが少なくなるような仕様が良 いと思います。 > 「情報は多い方が良い」とは限らない。むしろ場合分けが多く > なるかも。 反論します。普通のプログラムではこの例外はバグを示すため、rescue する 必要はありません。つまり、場合分けは多くなりません。 そして、例外は nil よりもバグを早期に検出します。nil を返した場合には 問題を検出するにはユーザが自分で検査しなければいけませんが、例外ならな にも書かないで検出されます。 もちろん、多くの場合、正しいプログラムは比較できないものを比較したりは しないので、これはユーザがバグを追いかけているといった状況の話です。 例外にしておけば、なにもしなくても検査が入っている状況になり、ユーザは 無用にプログラムを疑わなくて済みます。 まぁ、<=> を直接使うのは主に sort のブロックで、その場合は nil を返せ ば例外になるから、この理由はちょっと弱いかもしれませんが。 > 半順序関係はクラス/モジュールだけだし、理由はともかく順 > 序関係が成立しないのだから、差別する必要はない。 反論します。この情報の欠落は反対称律の実現を厄介にします。 % ruby -rdelegate -e ' class C; end class D; end c = SimpleDelegator.new(C) p c < D p D < c ' nil -e:6:in `<': compared with non class/module (TypeError) from -e:6 例外を出すべきかどうかという条件判断を <=> がしてくれないため、その判 断を <, <=, >, >= に埋め込む必要があります。そして、<, <=, >, >= を <=> の呼び出しによって実現するのであれば、比較可能なクラスは相互に相手 を知っていなければなりません。その結果、比較可能な後からクラスが増える 状況を扱うのが困難になります。 もちろん、組み込みの中で半順序なのは Module だけで、Module と比較可能 なクラスを後から付け加えるというのは非現実的ですが、<=> というメソッド の使いかたの範を示すという意味でよろしくないと思います。 > * ないとすると、成立しない場合には、例外かnilか > > 例外だとエラーメッセージに内部利用されている<=>が登場す > ることになる これはまったく考えていませんでした。なるほど。 > これを避けるにはコストのかかる例外補足が必要 > > => nilの方が良い > > ということで、現状維持を推します。 > > nilから適切なメッセージを持つ例外に変換する方が、例外を補足 > して適切なメッセージで再発生させるのより安いというのも動機の > 一つです。 効率に関しては反論しません。 たしかに、上で述べたような利点を実現するのに引き合うかどうか、というバ ランスを考慮する必要はあると思います。 -- [田中 哲][たなか あきら][Tanaka Akira]