ごとけんです

精度の話と以前考えてた Bag には似たような側面がある
ことに気付いたので書きます。

# なにか大切なことのような気が(本能的に ^^;)している
# のですがポイントが何かいまいち解らないのでそれを
# 気付かせてくれる議論をしてくれる人がいればお願いします。

たとえば、倍々精度版の Float として DFloat という
ものを作った人がいたとします(あくまでも例えです)。
今までの作法では Float から DFloat の変換のためには
同名のメソッド DFloat(other) を用意してユーザーが

 foo = Float(num)
 bar = DFloat(foo)

などとしていたわけです。

一方、[ruby-list:9109] に由来するスレッドで、いま僕が
提案中の prec(klass) という演算精度を指定するメソッドは
たとえば 

 a = Matrix[[a11,a12],[a21,a22]]
 b = a.prec(DFloat)

のように使い、実装としては

 class Matrix
   def prec(klass)
     collect{|e| e.prec(klass)}
   end
 end

みたいなもので a の要素に再帰的に prec(DFloat) を
呼び出し、最終的に精度を担うオブジェクトが self に
対して DFloat に型変換を行った結果を返し、行列 b の
精度を DFloat にするというものです。
ですが、この方法だと組み込みクラスの手前か組み込み
クラス自体で prec(DFloat) が実装されている必要が
あります。
勿論、DFloat を実装する人が適切に実装すればすむの
でしょうが常にまだ知らないものに型変換することも
考えなければなりません。

で、思ったのは何かというと、こういう時のために、
精度を担うクラスには引数の個数をそろえた new か、
あるいは違う名前のメソッド、たとえば induced_from を
用意しておくと良いのではなかろうかと言うことです。
そういうのがあれば、たとえば、

def prec(klass)
  if klass in 自分が知ってる精度クラス達
    適切な処理をした結果
  else
    klass.induced_from(self)
  end
end

という書き方が出来るけど、現在のクラスと同名の
メソッドではこのようなことが出来ません。
さらに、自分が知ってる精度クラス達などを
known_precisions なんていうメソッドを用意して
おくことで prec を Mix-in の対象にすることも出来
そうです。

これは以前 Bag モジュールを検討した時、コンテナに
引数の個数が1のappend があればレシーバと同じクラスの
結果を返すcollect としての map_each や更に map_each! 
なんてのも楽に作れるのにと思ったのと少し似ていると
感じました。

-- gotoken