あおきです。
In mail "[ruby-list:31875] Re: 先祖がえり"
"T.Shirakawa" <niegh / dk.catv.ne.jp> wrote:
> 白川@質問者です。
> > ただ、そもそも組み込みクラス (特に String と Array) は可能な限り
> > 継承しないほうがいいでしょう。
>
> このあたりの感覚がまだ全然分かんないんですよね。
> なぜなのでしょう? 教えていただけますか?
うーん、そうですねえ……
今回の、継承してもメソッドを呼ぶと結局 String が返ってくるという
のがまずひとつの理由です。それから、file.gets とか Array.join など
でもやはり String が返ってきます。そういうのは返り値をもらってから
こちらで変換するなりラップするなりしないといけないわけで、それが
許されるならその場で process(string) みたいにすることも問題ない
ように思います。
> > メソッドの追加だけなので String に直接足してしまってもよさそうです。
>
> それも考えたのです。 (この辺りがなんか rubyってすごい
> って思ったりもして、ruby本読んでてわくわくしました。)
> ただ、例えば 親のメソッドをオーバーライトして、
> 親クラスをnewしたり、子クラスをnewしたりして
> 挙動を変えたい場合なんかに使えないなぁ などと
> 考えたりしていました。
確かにおっしゃる通りです。ただ、現実的に String.new をオーバーライド
する必要がある (or 適切である) 場面があまりないのではないかと思うんです。
> > あるいはそもそも String のメソッドにすべきでないかもしれません。
>
> やっぱり継承ではなく、ラッパークラスを作るべきなんでしょうか?
いや、ラッパーよりもクライアント側(メソッドを使うほう)のコードに
すべきだろうと思います。たとえば次のように。
class Client
def client_method
cols = csv_split(str)
....
end
def cvs_split( str ) # 欲しい機能
....
end
end
あるメソッドがどこにあるべきか、を決めるのはとても難しいんですが、
String にだけ関して言えば、String はデータ中心で構成されていますし、
オブジェクトネットワークの末端に位置するオブジェクトなので、
プログラム固有のアルゴリズムを記述する場所には向きません。
たとえば CSV (comma separated value) 形式の文字列をカンマで分割
するメソッドなんかは String に追加するべきではないでしょう。
このへんの可否の判断をするには、適当に 10 くらいプログラムを集めて、
そのうちいくつくらいがそのメソッドを使う可能性があるかどうかを
考えてみるといいと思います。5 つ 6 つくらいが使う可能性があると
思うなら追加する価値がありそうです。それ以下なら、処理する側に
コードを持たせるほうがいいでしょう。
いろいろ考えて、これは String にあるべきメソッドだと判断した場合も、
それが全く新しいメソッドならば単に追加だけで問題ないので継承する
必要はありません。既存のメソッドが気にいらない場合は、新しい名前を
付けてメソッドを追加するかクライアント側のコードで対処すべきでしょう。
でないとライブラリの挙動を保証できなくなります。
またラップする場合にはメソッドが減ることが多いようです。
-------------------------------------------------------------------
青木峰郎