0

以下のコードを参照してください。metaClass を使用してメソッドがクラスに追加される前に作成されたクラスの古いインスタンスは、メソッドを理解するべきではありませんか? 「PROBLEMATIC LINE」コメントの下の assert ステートメントは、古いparentDirインスタンスがblech()メッセージを理解できないため、そうすべきではないと思われるときに実行されます。

// derived from http://ssscripting.wordpress.com/2009/10/20/adding-methods-to-singular-objects-in-groovy/

// Adding a method to a single instance of a class

def thisDir = new File('.')

def parentDir = new File('..')

thisDir.metaClass.bla = { -> "bla: ${File.separator}" }

assert thisDir.bla() == "bla: ${File.separator}" : 'thisDir should understand how to respond to bla() message'

try {
    parentDir.bla()
    assert false : 'parentDir should NOT understand bla() message'
} catch (MissingMethodException mmex) {
    // do nothing : this is expected
}

// Adding a method to all instances of a class

File.metaClass.blech = { -> "blech: ${File.separator}" }

try {
    thisDir.blech()
    assert false : 'old instance thisDir should NOT understand blech() message'
} catch (MissingMethodException mmex) {
    // do nothing : this is expected
}

try {
    parentDir.blech()
    // PROBLEMATIC LINE BELOW - THE LINE IS EXECUTED WHEN
    // I THINK AN EXCEPTION SHOULD HAVE BEEN THROWN
    assert false : 'old instance parentDir should NOT understand blech() message'
} catch (MissingMethodException mmex) {
    // do nothing : this is expected
}

thisDir = new File('.')
parentDir = new File('..')

try {
    thisDir.bla()
    assert false : 'new instance thisDir should NOT understand bla() message'
} catch (MissingMethodException mmex) {
    // do nothing : this is expected
}

assert "blech: ${File.separator}" == thisDir.blech() : 'new instance thisDir should understand blech() message'
assert "blech: ${File.separator}" == parentDir.blech() : 'new instance parentDir should understand blech() message'
4

3 に答える 3

4

古いparentDirインスタンスはblech()メッセージを理解するべきではありません

それはどのようにmetaclass機能するかではありません。どうやらプロトタイプベースの OO 言語 (JavaScript?) から来ているようです。Groovy はプロトタイプベースではありません。クラスへの変更は、変更が行われる前に作成されたものを含む、クラスのすべてのインスタンスに影響します。

于 2009-10-25T14:55:44.410 に答える
0

スクリプトは で実行を終了しCaught: java.lang.AssertionError: old instance parentDir should NOT understand blech() message. Expression: false at x.run(x.groovy:35) ます。メソッドが機能することを期待していませんでしたblechか? Fileオブジェクトのメタクラスだけでなく、メタクラスに追加しているので、理由がわかりません。

于 2009-10-23T18:21:34.810 に答える
0

この線:

parentDir.blech()

あなたが言うように、 blech() が File に追加された後、正常に実行されます。しかし、その場合は、なぜそれ以上の呼び出しをしないのでしょうか:

thisDir.blech()

これはクラス File の別のインスタンスであり、blech() が既に File に追加されているためです (スローする例外をスローしません)。両方の呼び出しが MissingMethodException で失敗するか、両方が機能するはずです。一方が機能し、もう一方が機能しないのはばかげています。

于 2009-10-25T14:43:34.747 に答える