Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

differrence between Ruby and Python

9 views
Skip to first unread message

Shugo Maeda

unread,
Mar 2, 1998, 3:00:00 AM3/2/98
to

前田です。

suz...@otsl.co.jp (SUZUKI Hisao) wrote:

|>Mixinや特異メソッドのことかと思って一瞬びっくりしました。
|>クラスもオブジェクト...という部分ですね。
|
|いえいえ,全部についてです。

やはりちょっと違うという印象を受けました。
# どちらが良いかという問題は別にして。

|Python は Mixin よりも一般的で強力な (したがって誤用,乱用の
|危険もまた大きい) 多重継承をサポートしています。

fjでも何度もいっているのですが、RubyのMixinシステムの特長は言語
としてMixinを強制している点です。
多重継承ができれば、Mixinをコーディングスタイルとして利用できる、
というのは当たり前ですよね。

|Python は特異メソッドに相当することも可能です。(a) 各インス
|タンスは属性を随意に設けることができる,(b) 関数も値として使
|える,という二つの規則からの簡単な系です。たとえば
|
| def foo(a):
| def bar(x, self=a): print "<%s, %s>" % (self, x)
| a.f = bar
|
|という関数はインスタンス a に f という (事実上の) 特異メソッ
|ドを設けます (ここで入れ子関数の名前 bar は,a.f 自身のほか
|は関数 foo だけが知っています。名前空間の汚染はありません)。

なるほど、関数がfirst class objectだとこういうこともできるん
ですね。
Rubyの場合は特異メソッドは言語で規定されていて、

obj = Object.new
def obj.foo
print "foo\n"
end

のようにします。

クラスメソッドを定義する時はRubyではクラスオブジェクトの特異
メソッドを定義します。

|クラスもオブジェクトということについては,より正確にいえば,
|普通はクラスは (メタクラスの) インスタンスではないが,もしそ
|うしたければそうすることもできる,ということです。

僕が「クラスもオブジェクト」という言葉で表現したかったのは
Rubyがpureなオブジェクト指向言語である、ということでした。
結局僕がPythonよりRubyの方が好きなのはRubyはpureでPythonは
hybridだからなんですよね。

|>|# ただイテレータは Python ではごく制限された形態しかありません。
(snip)
|もっとも,ここで自分が念頭に置いていたのは for 文のことです。
|__getitem__ メソッドあるいはその名前の属性を適切に定義すれば,
|任意のインスタンスを for 文による繰返しにかけることができま
|す。この場合,自由変数うんぬんの問題はありませんが,繰返しの
|形態は for 文のそれに限るという制限を受けます。

なるほど、forのことでしたか。

|# イテレータ・ブロックをあらわす疑似変数を疑似仮引数として
|# メソッド定義の仮引数並びの次にでも明記するようにし,yield
|# もその疑似仮引数の関数呼出しとして表現すれば,より直感的
|# だったはずです。(そもそも yield という名前は,先行する諸
|# 言語で使われていた意味からのいらぬ誤解を招くので,かなり
|# 適切さに欠けるのではと思います)。

yieldはCLUから取ったんだと思うんですが。

|ところで,ruby でいう「イテレータ」,もとのアイディアは ETH
|Oberon-2 の
|
|H. M"ossenb"ock: Treating Statement Sequence as Block Objects,
|ACM SIGPLAN Notices, vol.27, no.8 (August 1992), pp.83-86.
|
|かとも察しますが,いかがでしょうか? >まつもとさん
|それとも独立して考案されたのでしょうか。

CLUのイテレータからforを分離したのだと思います。

|たとえば ruby が and や if の条件での正規表現リテラルを
|
| $_ =~ リテラル
|
|と見なすのは,特定の用途 (awk や Perl と同様の用途) には便利
|でしょう。しかし,ruby では,FALSE と nil 以外は真と見なすと
|いうルールがあるのですから,この場合,恒真でないのは一貫性の
|破綻ともいえます。これは汎用言語としては失点です。

=~はStringのメソッドでマッチしなかったらfalseを返すから
全然問題ないです。

他のクラスで

class Foo
def =~(arg)
...
end
end

のようにオーバーライドしても問題ないです。

|>rbc.rbという対話的にRubyの式を評価できるプログラムがあります。
|>対話的に処理する時はインデントしなくていい分Rubyの方が楽かもしれ
|>ませんね:-)
|
|手もとの LINUX JAPAN vol.6 に入っている版の ruby には入って
|いないようです。ただ,もしあったとしても,いくつか難点が予想
|されます。以下の点はどうでしょうか?
|
|(1) Python を python -i ファイル名 のように起動すると,
| ファイルをスクリプトとして実行後,対話処理に入ります。
| これはスクリプトを途中まで書いて,残りはその場その場の入力で
| 試行錯誤するのに重宝します。
| こういったことはできるのでしょうか?
| (スクリプト・ファイルを実行できるだけでは不十分です。
| まっさらな環境からの試行が1ステップで手軽にできることが
| 重要です)

デバッグ目的ならソースレベルデバッガがありますが、そういう
目的のものでしょうか?

|(2) Python の dir() 呼出しは,現在定義されている変数等の一覧を
| 返します。dir(引数) 呼出しは,その引数 (モジュールなど) の中
| で定義されている変数等の一覧を返します。
| 関数名を忘れたときなど,マニュアルをひくまでもなく,この一覧
| を見て確認すれば済むことがしばしばあります。
| こういったことはできるのでしょうか?

Rubyだとクラスオブジェクトにメッセージを送って調べます。

|(3) Python のモジュールやクラス,メソッド等,とりわけ,最近追加
| されてなじみのない (マニュアルを読みたくなるような) ものは,
| __doc__ 属性による説明文書が用意されています。
| これらは,マニュアルをひくまでもなく print 引数.__doc__ と
| することで,その場ですぐ説明を読むことができます (英語ですが)。
| こういった便宜はあるのでしょうか?

自分でライブラリをそう設計すれば同じことはできるでしょうが、
システムレベルでは用意されていません。

--
前田 修吾

Shugo Maeda

unread,
Mar 2, 1998, 3:00:00 AM3/2/98
to

前田です。

sh...@po.aianet.ne.jp (Shugo Maeda) wrote:

||たとえば ruby が and や if の条件での正規表現リテラルを
||
|| $_ =~ リテラル
||
||と見なすのは,特定の用途 (awk や Perl と同様の用途) には便利
||でしょう。しかし,ruby では,FALSE と nil 以外は真と見なすと
||いうルールがあるのですから,この場合,恒真でないのは一貫性の
||破綻ともいえます。これは汎用言語としては失点です。
|
|=~はStringのメソッドでマッチしなかったらfalseを返すから
|全然問題ないです。
|
|他のクラスで
|
|class Foo
| def =~(arg)
| ...
| end
|end
|
|のようにオーバーライドしても問題ないです。

読み違えてました。
鈴木さんが書いていたのは

if /foo/

のことだったんですね。
失礼しました。

--
前田 修吾

SUZUKI Hisao

unread,
Mar 3, 1998, 3:00:00 AM3/3/98
to

鈴木です。

記事 <86pvk5n1...@soleil.localnet.or.jp> より


>|Python は Mixin よりも一般的で強力な (したがって誤用,乱用の
>|危険もまた大きい) 多重継承をサポートしています。
>
>fjでも何度もいっているのですが、RubyのMixinシステムの特長は言語
>としてMixinを強制している点です。
>多重継承ができれば、Mixinをコーディングスタイルとして利用できる、
>というのは当たり前ですよね。

それが Python では必ずしもそうではなくて,
メタクラスを適切に定義してやれば,
クラス定義の評価が終わった時点で (ということは,つまり,
スクリプト・ファイルの読込みが終わるのとほぼ同時に,
ということは,つまり,事実上,静的に),
そのクラスの基底クラス等の各種設定について,
自己反映的に与えられた情報を元に,
任意に決めた制約によるチェックをかけることも
決して不可能ではありません。

ですから,よこしまな多重継承をしているのを,この時点で
ハネることも,もしやろうと思えば可能なわけです。

# チェックによる効率の低下が気になるなら,
# 最適化実行のときには省略される assert とか
# if __debug__: ... とかを使えば OK でせう。

残る大問題は,そういうメタクラスを定義することですが,
これが結構な大仕事で,今のところは *絵にかいた餅* です >_<

# 誰かもう作っているかもしれませんが…。

--
SUZUKI Hisao >>> def fib(n): return reduce(lambda x, y:
suz...@otsl.co.jp ... [x[0] + x[1]] + x, [None]*n, [1L, 1L])

Shugo Maeda

unread,
Mar 3, 1998, 3:00:00 AM3/3/98
to

前田です。

suz...@otsl.co.jp (SUZUKI Hisao) wrote:

|>多重継承ができれば、Mixinをコーディングスタイルとして利用できる、
|>というのは当たり前ですよね。
|
|それが Python では必ずしもそうではなくて,
|メタクラスを適切に定義してやれば,
|クラス定義の評価が終わった時点で (ということは,つまり,
|スクリプト・ファイルの読込みが終わるのとほぼ同時に,
|ということは,つまり,事実上,静的に),
|そのクラスの基底クラス等の各種設定について,
|自己反映的に与えられた情報を元に,
|任意に決めた制約によるチェックをかけることも
|決して不可能ではありません。
|
|ですから,よこしまな多重継承をしているのを,この時点で
|ハネることも,もしやろうと思えば可能なわけです。

そういうライブラリを用意して、みながそれを利用すれば、ということ
ですよね?

やはり言語として多重継承ができるなら、それをそのまま使ってしまう
人が多いのではないかと思います。
Rubyみたいに言語で強制していると、自然にMixinのスタイルが身に付き
ますよね。
そういう意味でRubyが言語仕様にMixinを採用しているという点は大きな
利点になっていると思います。

--
前田 修吾

0 new messages