けいじゅ@日本ラショナルソフトウェアです.

In [ruby-dev :7710 ] the message: "[ruby-dev:7710] Re: [ruby-ext:00382] New coerce scheme ", on Aug/18 09:16(JST) 
Shin-ichiro Hara writes: 

>原です。

>|> この方法で気になるのは, ほとんど同じアルゴリズムを持つ演算が2つづつ必要
>|> になりますよね.
>|
>|  でも例えば matrix.rb では Matrix に対する左側からの演算は
>|Scaler の方に書かれているわけで見た目クラスがわかれている
>|だけで実質2つずつ書かれているのと同じですよね。
>
>同じですね。しかしこれは「行列*スカラー」と「スカラー*行列」
>がたまたま同じだった(似ていた)だけだで、他のものどうしだった
>ら違う場合もあり得るわけです。

おなじなんですけど. Matrixはcoerceでうまく対応できなかった悪い例というこ
とで...

>けいじゅさんの問題にしているのは、すでに
>
>  Ba Bb
>  Aa Ab
>
>という計算表がある時に C (= c) というクラスを加えて
>
>  Ca Cb Cc
>  Ba Bb Bc
>  Aa Ab Ac
>
>という計算表の Cc の部分を2回記述するのがいやといいう事で
>しょう。Ca と Ac、Cb と Bc がたまたま一致しても無駄ではな
>い。(実際違う場合もありうるから。)
>
>私の案は「C の op に Ca Cb Cc を、op! に Bc Ac を定義させよ」
>という感じかな。

おお. 非常にわかりやすい. でも, 現行のcoerceの理想は

  Ba Bb
  Aa Ab

という計算表がある時に C (= c) というクラスを加えたとき

  Ca Cb Cc
  Ba Bb Cc = c.coerce(B)c
  Aa Ab Cc = c.coerce(A)c

これで済むようにしているんですよね. 

で思ったんですが, coerceをもっと改良すると

  Cc Cc Cc
  Ba Bb Cc
  Aa Ab Cc 

にできそうですよね. この件は後で--(*)

>|  方針としては、
>|・基本的に(iii)を使う。
>|・(iii)に書くと不自然になるものは(ii)で書く。
>|です。
>
>そうなんですか? 私は基本的には (ii) を使うのではないかと。
>
>coerce の問題点は、Cb と Bc の様に形式として対称であるは
>ずの処理が全然対称に見えなかったりすることと、利用法が定
>まっていず、各クラスの間で紳士協定があるだけだということ
>です。何でもありえるので、とんでもない coerce を書いて正
>しく計算する人が出てくるかもしれない。
>
>だから、coerce を書かなくてすむなら、coerce なしで済ませ
>るというのが私の案です。多くの場合に当てはまるのではない
>かと。

先ほどの例でもあるようにcoerceが使えるなら使ったほうがコーディング料は減
ると思うんですよね. それに演算を行なうこととcoerce(型変換)を行なうことは,
本質的に違うので分離できるならしたほうがよいのではと思います.

>Scalar は、行列の事を知っているスカラーという意味ですよ
>ね。下位の事を上位は知らなくていいという協定を破っていま
>すね。紳士的な協定破りで面白いけど。(^^

ああ. Matrixの話はしないで(^^;;; そうしないと実装できなかったのですもの.


(*)
豊福さんの改良した案です:

class Numeric
  def +(other)
    begin
      o, s = self.coerce(other)
      s + o
    rescue  CantConvertion
      other +! self
    end
  end

  def +!(other)
    begin
      o, s = self.coerce(other)
      s + o
    rescue  CantConvertion
      fail CantConversion
    end
  end
end

class ANum
  def +(other)
    if  self.type == other.type
        #演算
    else
      super
    end
  end
end

1. 同じクラス同士の演算だったら計算する
2. 違っていたら, 自分のcoerceを用いて計算する
3. 自分のcoerceが知らなかったら, +!を呼び出す
4. other#+!があればそれを実行(option)
5. Numeric#+!で, 相手にcoerceしてもらい再演算.

4に関しては, 豊福さんの言う通り単純にcoerceするだけでは対応できない用で
す. 

この案だと, 基本的には演算に関しては自分同士しか考えなくてよいので, 非常
に管理が楽になるかなと...

あとは, coerceそのものの面倒くささをどうするかですが.
__
..............................石塚 圭樹@日本ラショナルソフトウェア...
----------------------------------->> e-mail: keiju / rational.com <<---