From: Yukihiro Matsumoto Date: 2009-12-07T12:42:17+09:00 Subject: [ruby-dev:39851] Time.now + str と #to_r まつもと ゆきひろです [ruby-core:23729]で指摘されたTimeとstringの加算がエラーにな らない理由は、1.9でRationalが組み込まれたことで、 * String#to_rが提供された * String#to_rはRationalとして解釈できない文字列に0を返す * timeが内部計算にRationalを使うようになった * timeがオペランドの変換にto_rを使うようになった というコンボによって発生しました。いちおう、Time#+の正当な引 数として文字列(T_STRINGおよびto_strを持つオブジェクト)を外す という対応を行いましたが、生煮え感がぬぐえません。 気に入らない原因を改めて考えてみましたが、どうやら以下の複合 のようです。 * to_rという名前はよくない。rがrationalだかregexpだかrange だかわからない。長年の利用でもう定着してしまった s(string), i(integer), a(array)は仕方がないとしても、これ 以上1文字to_?メソッドを増やすべきではない。この点では BigDecimal#to_dも同罪 * Timeがto_rを使っているのもよくない。名前が良くないことに加 えて、オペランドの暗黙の型変換のための(to_intのような)メ ソッドは、明示的な型変換を行う(to_iのような)メソッドと分 離されているべきであろう。 * しかし、Rationalは現状そのようなメソッドを提供していない (実装はある)。 * そもそもto_iとto_intのような、明示的な変換と暗黙的な変換の ペアのための統一的なネーミングルールがない。 ということで、手元で以下のような変更を行う(かなり大きめの)パッ チを作ってみましたが、これでも満足できません。 * to_rとto_dを削除 * 明示的な変換はas_xxx、暗黙的な変換はto_xxx * to_iなどにはas_intという別名 * 基本的クラス(int,str,ary)以外はフルネーム.to_lower * よってTimeの変換にはto_rationalを使う このパッチの最大の弱点は作った本人もtoとasがどっちがどっちだ か忘れてしまうというところでしょう。また、変更の規模が大きい ので1.9.2には手遅れという感もあります。私としてはto_rやto_dが これ以上広まらないうちに手を打ちたいのですが、そのへんは Yuguiさんの判断に任せるとして。 で、明示的な変換と暗黙的な変換のための命名原則はどのようなも のがよいのか、という点について、いろいろとご意見を聞かせてく ださいませ。あるいは上記問題のまったく別の解決方法が思いつい た場合には、それも聞きたいです。数の相互型変換を行うようなシ ステムの構築という解もありえるかもしれません。 あと、現状では明示的な変換の方は "foo".to_i # => 0 のような、わりとカジュアルな変換をしていますが、これはうれし いことが少ないので、今後新たに追加する場合は(Raional も含め て)、エラーをあげるべきではないかと思うようになりましたが、こ れはまた別の話として議論すべきでしょう。 まつもと ゆきひろ /:|)