2009-04-04 8 views
14

多くの議論では、人々が言語に関する予約を表明しているRubyについて聞いたことがありますが、サルのパッチ適用の問題が主要な懸案事項の1つです。RubyとPythonの両方でサルのパッチ適用が許可されている場合、なぜRubyではより議論の余地がありますか?

しかし、Python言語でも許可されていますが、Pythonのコンテキストで行われたのと同じ議論を聞くことはめったにありません。

この区別はなんですか?

この機能のリスクを最小限に抑えるために、Pythonにはさまざまな種類のセーフガードが含まれていますか?

+1

Rubyの場合と同じようにPythonよりもJavascriptでよく見られますが、そうでなければ –

答えて

16

、私は、Pythonが普及し始めているときには、皮肉なことが多少あると思います。

CとJavaプログラマはPythonを実際の言語ではなく、そのタイプの動的な性質が危険であり、人々が「悪い」コードを作成することを許していると言っています。 Pythonはもっと普及するようになった、とその急速な開発時間の利点が明らかになったとおり、あまり詳細な構文は言うまでもありません:

// Java 
Person p = new Person(); 
# Python 
p = Person() 

我々はいくつかのより多くの動的な機能は、Javaのそれ以降のバージョンで表示され始めました。 Autoboxingと-unboxingは、プリミティブを処理するのが面倒ではなく、Genericsは一度コードを作成して多くの型に適用することができます。

私は、Ruby - Monkey Patchingの主要な柔軟な機能の1つが、Pythonの群衆によって危険であると宣伝されていたことを少し楽しんでいました。今年はRubyを学生に教え始めたので、既存のクラス(システムの一部であっても)の実装を「修正」できることは非常に強力だと思います。

確かに、あなたはひどくねじれて、プログラムがクラッシュする可能性があります。私もCで簡単にセグメンテーションすることができます。そして、Javaアプリケーションは、炎上して死にます。

真実ですが、私はモンキーパッチを動的プログラミングとメタプログラミングの次のステップと見ています。それはSmalltalk以来のことだったので面白い。 Pythonで

+3

「ダックパンチング」という言葉は、「猿のパッチ」 "それは "アヒルタイピング"(それがアヒルのように突き刺すならば、それが整数であってもアヒルであるかもしれない)の演劇のビットです。もしそれがアヒルのように突っ込むことがなければ、あなたがパンチするまで(新しい方法を追加するなど)。 –

15

言語によって許可される可能性がありますが、どちらのコミュニティもその練習を許しません。 Monkeypatchingはどちらの言語でも許されませんが、Rubyではそれを頻繁に聞きます。オープンクラスのため、クラスをmonkeypatchするのが非常に簡単になります。it's more acceptable in the Ruby community, but still frowned upon。 MonkeypatchingはPythonではあまり一般的ではないし、簡単ではありません。なぜなら、そのコミュニティで同じことを聞いていないからです。 Pythonは、Rubyがその習慣を妨害するために何もしません。

class MyClass 
    def foo 
    puts "foo" 
    end 
end 
class MyClass 
    def bar 
    puts "bar" 
    end 
end 

はPythonで、この一方で、あなたは二つの方法、foobarを含むクラスを提供します:

あなたはRubyでより頻繁にそれについて読む/聞く理由は、このRubyでということです:

class MyClass: 
    def foo(self): 
     print "foo" 
class MyClass: 
    def bar(self): 
     print "bar" 

しかメートルを含むクラスであなたを残しますクラスの再定義が前の定義を完全に壊すので、barのようになります。 Rubyのバージョンよりも硬い

class MyClass: 
    def foo(self): 
     print "foo" 
def bar(self): 
    print "bar" 
MyClass.bar = bar 

:Pythonでモンキーパッチするには、実際にこれを記述する必要があります。それだけで、RubyコードはPythonコードよりもはるかに簡単にMonkeypatchできます。

+0

あなたのPythonの例も有効です。 2番目の定義は新しいMyClassクラスを作成するだけで、前のものを拡張しません(私はそれがルビのしていることだと思います)。 –

+0

技術的に有効であるというメモを追加することをお勧めします。 – hasen

+0

Rubyの "コミュニティ"がその習慣を許さないことを示す参考資料を提供できますか? ActiveSupport :: CoreExtensionsはどうですか? –

13

"Pythonには、この機能のリスクを最小限に抑えるためのさまざまなタイプのセーフガードが含まれていますか?

はい。コミュニティはそれを拒否します。保障措置は完全に社会的です。

21

これは、Pythonの「コア」クラス(C言語で実装されているクラス)が実際には変更できないため、Pythonではあまり実用化されていない手法です。一方、Rubyでは、内部的に実装されているため(それほど優れていない、まったく異なる)、何かについては動的に変更することができます。

哲学的には、Rubyの世界ではPythonコミュニティの中でぼやける傾向があります。なぜあなたはそれがもっと議論の余地があると主張しているのかわかりません(権威ある参照にリンクすることはできますか?) - 私の経験は、ユーザが可能性のある結果を知っているべきであれば、

+0

私はRubyコミュニティについては話すことができないので、そこではMonkeypatchingが受け入れられるというあなたの言葉を取り上げますが、Python開発者の部屋に入り込んでRubyについて考えてみると、 「猿のパッチを当てる」という言葉が現れないようにしてください。正の光ではありません。 –

+0

はい、しかし、「Pythonプログラマーの間では議論の余地があります」とは、「Rubプログラマーの間で論争があります」とは異なります。 Pythonで猿のパッチを当てることは可能ですが(時には有益だが危険だと認識されています)、積極的に奨励しているRubyの言語機能がいくつかあります。 –

+0

(argh、上記のRubyプログラマーの間では、もちろん議論の余地があるはずです) –

3

実際には、Pythonでは基本型を変更するのが少し難しくなります。

たとえば、整数を再定義するとします。

ルビー:

class Fixnum 
    def *(n) 
     5 
    end 
end 

今2 * 2利回り5.

のPython:ルビーの味を持っていた(そしてそれが好き)しているPythonプログラマとして

>>> class int(int): 
    def __mul__(self, x): 
     return 5 


>>> 2*2 
4 
>>> int(2)*int(2) 
5 
+0

Rubyの例では、あなたが考えることをしていません。そうすれば、Integer.times {| 5 | "数字は#{5 + 1}"未満の数字で、6を返します。しかし、2 * 2はまだ4です。Fixnumクラスが必要です。 def *(n); 5;終わり;終わり 。 – Chuck

+0

@Chuck:ありがとう、私は本当にRubyの経験はまだありません(まだ)、私はPythonの男です;-) – vartec

3

、任意のリテラル(""{}1.0、など)は、あなたがそれをモンキーパッチしようとしたし、あなたの名前空間に対応するクラスを再定義した場合でも、標準クラスのインスタンスを作成します。

それはちょうどあなたが意図したどのように動作しません。

class str(): 
    # define your custom string type 
    ... 

a = "foo"  # still a real Python string 
a = str("foo") # only this uses your custom class 
+0

Rubyは同じように動作するので、違いはありません。もし私が 'def String.new(* args、&block);アレイ。新しい; 'string'new(" foo ")'の結果は '[]'になりますが、 '' foo''は '' foo' 'になります。 –

+0

ruby​​のこのビットを考慮してください: –

2

私は猿のパッチ適用が唯一の最後の解決策として使用すべきであると思います。

通常、Pythonプログラマは、クラスまたはメソッドがどのように動作するかを知っています。彼らはクラスxxxがある方法で物事をしていることを知っています。

あなたがサルをクラスまたはメソッドに適用すると、その動作が変更されます。このクラスを使用している他のPythonプログラマは、そのクラスの動作が異なると非常に驚くことがあります。

通常のやり方はサブクラス化です。そうすれば、他のプログラマーは彼らが別のオブジェクトを使用していることを知ることができます。彼らは元のクラスまたはサブクラスを使用することができます。

+0

スクリプトを使用する他のPythonプログラマーがいない場合はどうなりますか?またはスクリプトが短いですか?私たちが聞いている「危険な」議論の種類は、50 + kLOCプロジェクトを扱うときに非常に有効です。しかし、小規模のスクリプトの場合、金銭的なパッチが適用できないということは、数行からなるスクリプトの場合、数十から数百の定型文を意味する可能性があります。私は小規模のスクリプト(有能なプログラマーが数分間で全部を読んで覚えることができる)のために、「たるんだPython」が大好きです。ほとんどのソフトウェアエンジニアリング分野は大規模なプロジェクトのためのものです。 –

1

Pythonでいくつかのサルパッチを行いたいのであれば、組み込み型(int、float、str)を変更しない限り、比較的簡単です。

class SomeClass: 
    def foo(self): 
     print "foo" 

def tempfunc(self): 
    print "bar" 
SomeClass.bar = tempfunc 
del tempfunc 

これは、バーメソッドをSomeClassに追加し、そのクラスの既存のインスタンスでも、その注入メソッドを使用できます。

+0

また、monkey-patchableではない:datetime.datetime、datetime.timedeltaなど、多くのものがあります。恥、私はこれらのクラスを頻繁に拡張したいと思う方法があるので。 –

関連する問題