2009-08-24 5 views
4

私は、私が制御しないクラスにメソッドを追加したいという問題に直面することがよくあります。たとえば、統合されたAPIを持たないさまざまなオブジェクトタイプ(たとえば、__str__のメソッド)で操作できる関数prettyPrintが必要な場合があります。ScalaやJythonのマルチメソッドの代わり

Nice言語とRは、Visitor Patternをうまく回避しないマルチメソッドを使用してこれを実行します。例えば、Rplot()の機能を持っています。個々のプログラマは、データ型(例えば、ネットワークグラフまたは株価データ)を定義するための新しいクラスを作成することができる。セカンダリユーザ/プログラマは、グラフや株式ティッカーコード、または他のプロット関数のコードにアクセスできないにもかかわらず、機能を記入するためのプロット関数を書くことができます。

class.method()を使用して、後でたくさんの機能を追加したいと考えているため、実行不可能なようです。各タイプのclass_plot()の機能がたくさんあることも悪い考えです。タイプをチェックする1つの大きいplot()関数を定義することは拡張可能ではありません。

マルチメソッドの代替手段は何ですか?特に、JythonとScalaで動作するデザインに興味があります。

答えて

7

Scalaでのクラスにメソッドを追加する最も簡単な方法:

implicit def defSum(l: List[Double]): Double = new AnyRef { def sum = l.foldLeft(0.0)(_ + _) } 

かを、Scalaの2.8上で、メソッドの処理番号の特定のケースで、これだけISN

implicit def defSum[T](l: List[T])(implicit n: Numeric[T]) = new AnyRef { 
    import n.mkNumericOps 
    def sum = l.foldLeft(n.zero)(_ + _) 
} 

」 Scala 2.8で必要とされているのは、既にsumと定義されているからです。インスタンス化するときにも特徴を追加することができます

// Immutable class 
case class Point(x: Int, y: Int) 

// Somewhere else in the code  
trait MyPlot { 
    self: Point => 
    import self._ 

    def plot = println("At "+x+", "+y) 
} 

// Usage 
val p = new Point(1,2) with MyPlot 
p.plot 

あなたを行うことができない何を対象に(実行時の代わりに、コンパイル時に、すなわち)動的にメソッドを追加することです。最初のケースでは、「このメソッドをこのクラスに追加する」と言っています。後者の場合、「この特性でこのオブジェクトを作成する」と言っています。これらは大丈夫ですが、 "このメソッドをこのオブジェクトに追加する"はできません。

1

PythonとJythonのあなたの「拡張」メソッドを保持するために、これらを使用することができますので、ミックスインクラスを許可:

class Derived(Base, Mixin1, Mixin2, ...): 
    ... 

あなたは、異なるタイプのためplot方法のホストをしたい場合は明らかに、あなたはどこかに実装を持っている必要がありますこれは複数のmixinクラスにつながる可能性があります。代わりに、キーがタイプで値が関数(または関数のセット)である辞書を使用することができます:this answerを参照してください。

私はまたあなたが猿パッチクラスを望んでいないと仮定していますが、これは技術的にも可能です(お勧めできませんが)。

関連する問題