作者: HIDAKA Takahiro
日時: 2002/4/02(22:55)
 ひだかです。

ねこ丸 <QYE07500@...> wrote:

>  ねこ丸です。
> 
>   これならレベル下げに貢献できそうだ(^^;
> 
>   オブジェクト指向ではすべてオブジェクトなのかと思っていましたが、実装と
> してはそうでもないんですか。

 Rubyに限って言えば逆で、全てがオブジェクトなんだけど、
意識しなくても書ける言語ということになるとおもいます。

 C++とかJavaとかは、オブジェクトとそうでないものの区別の
ある言語です。

> >  なぜ、そこまでオブジェクト指向が優れていると思っていますか?:)
>   かっこいいから。
>   なぜかっこいいと思うかって、オブジェクト指向がよく分からないから(アホ)

 あはは(^^)

>   なんかどうも最近のものは変にオブジェクト指向を(自分が)意識しすぎてし
> まうせいか、手軽に使い始めるのに抵抗を感じるんですよね。でもオブジェクト
> 指向を意識する必要はないと言われるとそれはそれでなんか淋しい。やるからに
> はなんか新しいことが身につくから嬉しい。
> 
>   例えば初めて関数を使ってプログラムを簡素化できたときのように、例えば初
> めて正規表現を使って MS-DOS のワイルドカードにはないパワーに感動したとき
> のように、例えば初めてポインタで文字列を操作してみたときのように、オブジ
> ェクト指向を実現したスクリプト言語で初めてオブジェクト指向に触れて感動す
> るのに適した素材ってなんでしょう?
> 
> # いや、Ruby や Python でフィルタ書いちゃいけないって意味じゃなくてね。

 初めてオブジェクト指向に感動したのはなんだったか忘れてしまったのですが。
というか当時はC++しか知らなかったな。

 ちょっとオブジェクト指向っぽい例かなぁと思うものを3つほど。


 最初の例として、RubyとPerlのぼくにとっての大きな違いの例なんですけど、
split関数があります。

 Perl では、split(/:/, string) とやると、文字列を : で区切った
リストにしてくれます。

 Ruby では、同じことが string.split(/:/) になります。

 ぼくは、Perlを常用しないせいもあるんですけど、引数の順序が
覚えられないんですね(^^;; バカっぽい理由で申し訳ないんですけど、
これが Perl を好きじゃなくなったひとつの理由だったりします。いや、
たまたま引数を逆に書いてしまって動かなくて悩んだとき以来の
さかうらみみたいなもんなのはわかってるんですけどね。。


 ふたつめの例として多態の例をあげてみましょうか。
Rubyに昔からあるけれど標準添付されてこなくて、次期バージョンから
入ることになっているライブラリに、StringIO というのがあります。

 これを使えば、ファイル操作と同じメソッド群で文字列操作ができます。

 ということは、def foo(f) として、File クラスのオブジェクトfを
受け取ることを期待して作った関数があったとしても、StringIO の
オブジェクトを渡せば文字列として結果を返してもらうことができます。
foo には全く手を入れる必要はありません。


 もうひとつの例として、今作っている(けど全然進まない)スクリプトで、
プレーンテキスト解析ライブラリみたいなものを考えています。
こっちはクラスを作る話。

 もともとは、RFC のテキストファイルをHTML化するスクリプトを
書いていて(これはすでにできた)、それとは別で、メールをHTML化して、
要約つきダイジェストをつくる(要するに ruby-list ML のアーカイブみたいな
もの)スクリプトを書きたくなって、いまちょっとずつ書いてます。

 で、なぜライブラリになるかというと、

・段落ごとに空行で区切られている
・ときどきソースコード断片とかがでてくる(それは字下げされていたりする)

といった共通性がくくりだせないかなーと思っています。

 このときに、

・ファイル全体
・空行で区切られたもの = 段落
  ・地の文の段落
  ・字下げされた段落
  ・引用記号がついた段落

みたいなものを共通のライブラリ側のクラスとして用意して、
RFC変換スクリプトでは、さらに

・章番号つきのタイトル(これも空行で区切られているから段落に見える)
・目次

なんかのクラスが追加され、
メール変換スクリプトでは、

・メールヘッダ部分
・あいさつっぽい段落
・シグネチャっぽい段落
・ソースプログラムっぽい段落

とかいうクラスを追加しようとしています。

 でも、ファイルは段落の集合体であることに変わりはないので、
段落クラスに to_html メソッドを用意して、それぞれの段落の
HTML変換方法を定義してやれば、ファイルをHTMLに変換するのは、

  class TextFile
    def to_html
      paragraphs.each { | p |
        output.print p.to_html
      }
    end
  end

でできることに変わりはないわけです。

 もっと言えば、段落はクラスに分かれると言っては見たものの、
どのクラスに分類されるかはテキストファイルから自明にわかる
わけでもない(例えば、1行だけのあいさつは字下げされた
段落ともとれる)ので、各クラスに、isValid? クラスメソッドを
用意して、どの種類の段落に分類できる可能性があるかを
判定しています。その結果の組み合わせから、最も妥当な
段落に分類するのは、段落分類メソッド(factory method)の
仕事にわりふっています。

 段落の種類が増えたら、段落分類メソッドは多少手を入れる
必要はありますけど、isValid? メソッドは基本的に手を入れなくても
いいように作るつもりです。

 うーむ。ややこしい例になってしまったかなぁ。

 あともうひとつのメリットとしては、全てがオブジェクトなので
例えばArrayやHashになんでも入れられて、しかもHashのキーにも
できる(共通基底クラスObjectの利点)、というのがあるんだと思う
のですが、いい例が思いつきません(^^;

# もっといい例が出てくることに期待しましょう。。。

-- 
ひだかたかひろ  cv8t-hdk@...-net.or.jp