From: Shin-ichiro HARA Date: 2001-02-26T23:55:00+09:00 Subject: [ruby-list:28320] Re: Cast 原です。 >In message "[ruby-list:28300] Re: Cast" > on 01/02/26, toyofuku@juice.or.jp writes: > > 複素数 x + yi から行列への変換というとき、 > > > >(1) [x + yi] > >(2) [x, y] > >(3) [[x, -y], [y, x]] > > > >の3通りを考えるのですが、一つの casting では複数の変換に > >対応できないということはないですか。 これはいい質問をしてもらいました。答えは「実装によるけど、多分キャ スト不能(例外)」というものです。(^^; 今まで議論された coerce や prec によるキャストの話は、既存クラスを 変更することになしに、新しいクラスへの変換を可能にする仕組みでした が、今回のアイデアはそれらとちょっと違います。 一つは、今まで String()、Integer()、Array() といったキャスト用の関 数すなわち Object のメソッドが定義されていたのですが、これはやや場 当たり的な感があります。これを Class のメソッド ** を使って klass ** () とすることにより、よりオブジェクト指向的なスタイルにな るのではないか?と、いうことです。ただしこれは、新しいユーザー定義 クラスに対しては、有効に働く場合もあるし、そうでない場合もあります。 うまくいかなければ、Class#** を再定義するか、あきらめるかのどちらか です。あきらめることも念頭に置かれているところが、ユニークなところ です。(これでいいのだ。) もう一つは、組み込みクラスを継承した場合の変換を楽にするということ です。例えば Array を継承して機能を拡張した Array2 を作ったとして、 Array2.new(0, 1, 2, 3) としても、[0, 1, 2, 3] の機能拡張版ができるわけではありません。そ れを作るには,、現在でも Array2[0, 1, 2, 3] で、所望のものが得られるのですが、これは Array[] がたまたま便利な ように作られていたことによっていて、統一感がありません。また、すで にある配列から Array2 オブジェクトを作りたい場合、例えば Array2[* str.split] などとしなければならず、少なくとも見た目には「展開してからまた同じ ようなものを構成する」という形式を取らざるをえません。 そこで、今回の casting によって Array2 ** str.split というのが可能であるならば、実装によってはかなりローコストにキャスト をするのが可能ではないか、ということなのです。もちろん、ローコストと いっても dup より重くなるのは必然ですが。 これができると、従来、委譲によって実装していたクラスの多くを継承によ って手軽に構成するようになると思います。もちろん、それがよくない場合 もあるけど、それでよい場合も多いと思うのです。 以下、別の話。 >Ax = zx という方程式は (A-zE)x = 0 と同一視されますよね。だ >から行列へのキャストがあるとすれば z*E ではないですかねぇ。 >それ以外はおっしゃるように多義的なので意味が分からないと思い >ます。ただし複素数 z に対してはEの次元を指定しないと自明な変 >換は存在しないでしょう。 これで豊福さんのとあわせて4通りですね。これは、数同士のキャ ストが一通りではないことを示すよい例になっていますね。したが って coerce 一本槍で「自然なキャスト」を定義するのは無理があ ることの証明になっている。:-) >そういえば、クラス定義で class に続くものを式にも出来ないで >しょうか。無名クラス Foo(n) に対して「class Foo(n) … end」 >のように書きたいことがしばしばあります。 > >-- Gotoken 無名クラスをがんがん使いたいときはありますよね。これは面白い アイデアだと思います。