2

次のような状況があるとしましょう。

;; Capture whatever the print word pointed to into a variable
outer-print: :print

foo: context [
    ;; within foo, override print and implement in terms of outer-print
    print: func [value] [
        outer-print "About to print"
        outer-print value
        outer-print "Done printing"
    ]
]

これを行うことができます。または、外部コンテキストから必要なものが複数ある場合は、明示的にキャプチャできます。

;; Capture current context into something called outer
outer: self

foo: context [
    ;; within foo, override print and implement in terms of outer/print
    print: func [value] [
        outer/print "About to print"
        outer/print value
        outer/print "Done printing"
    ]
]

これは正しいイディオムですか、それとももっと良い方法はありますか? これにより、期待した結果が得られない状況はありますか?

4

2 に答える 2

2

これは良いスタイルです。特に 2 番目のスタイルはより柔軟で、あいまいさなしに外側のプリントのすべての用途に大量の影響を与えることができます。直接バインディングを使用する場合、outer-print という単語が再定義されるか、2 つの呼び出しの間でコンテキストが変化make foo [] し、最終的に 2 つの異なるバインディングを指す場合があります。

静的シンボルの解決

完全を期すために、余分な単語を設定する必要のない 3 番目の選択肢があります。適切な名前がありません。より良いタイトルを提案してください。

このメソッドは、関数値を直接使用するため、バインディングの問題を回避します。

foo: context compose/deep [
    ;; within foo, override print and implement using native print directly
    print: func [value] [
        (:print) "About to print"
        (:print) value
        (:print) "Done printing"
    ]
]

ここで興味深いのはSOURCE、内部の印刷機能の場合です。

>> p: get in foo 'print   
>> SOURCE P
== p: func [value][native "About to print" native value native "Done printing"]

printのnative が、それを参照する単語ではなく、本文で直接使用されていることを確認してください。

実際、これはおそらく純粋な REBOL で何らかの形式のコンパイルに到達できる最も近いものです。常にシンボルを使用してフェッチおよび評価する代わりに、上記のように reduce または compose を使用して手動で単純に静的に解決できます。

長所:

高度で悪意のあるバインディング コードによってハイジャックされることは決してありません。つまりPRINT、ANY および ALL コンテキストに直接の単語境界がなくても、本体内の元の関数への直接参照が引き続き存在します。

短所:

これは非常に静的なコーディング方法であり、あまり「廃止」されていません。

于 2013-05-28T14:43:05.207 に答える
2

;; Capture current context into something called outer

コメントは、Rebol に何らかの「現在のコンテキスト」があると考えていることを示唆しています。それは誤りです。すべての単語には独自のコンテキストがあります。したがって、場合によっては、

outer: self

コードが期待どおりに動作しません。たとえば、2 つの変数「print」と「set」にアクセスするとします。単語が異なる「外部」コンテキストを持つことは可能です。その場合、トリックは少なくとも 1 つの単語に対しては確実に機能しませんが、実際には両方に対して機能しない可能性があります。

于 2013-05-29T00:26:35.557 に答える