18

メタデータを必要とするという制限がないだけで、動的シンボルに対してwith-redefsできることはすべてできるように思えます。では、いつどちらを使用する必要がありますか?binding^:dynamic

4

1 に答える 1

17

^:dynamicは、メタデータを要求するbindingだけでなく、現在のスレッドでのみ表示されるバインディングも作成しますが、 によって作成されたバインディングはwith-redefsすべてのスレッドで表示されます。そのためwith-redefs、非常に鈍いツールであり、同じ VM で実行されている他のコードに影響を与える可能性があります。テスト コード以外で使用されているのを見たことがありませwith-redefsんし、そうすべきでもありません (少なくとも私の意見では)。

2つの違いを要約すると、次のようになります。

  • ^:dynamicでバインドすると、制御された方法で動的な動作を少し導入できます。これは、API で拡張ポイントを定義する良い方法です。呼び出しチェーンのはるか上にある呼び出し元が、呼び出しスタック全体でパラメーターを明示的に渡さなくてもコードの動作を変更できるようにします (その中にはコードでさえないものもあります)。
  • with-redefsは自由に使用できます。たとえば、テスト対象の関数に多くの依存関係がある場合にサブシステム全体をモックアウトする場合など、テストに役立ちます。

var を として宣言することは^:dynamic、イヤーマフを使用して動的 var に名前を付ける慣例 (例: *my-dynamic-var*) と共に、コードのその部分を動的に変更できることを呼び出し元に通知する自己文書化の方法であるという追加のボーナスがあります。

要約すると、API とプロダクション コードを記述するときは、 ^:dynamicバインディングを優先します。テストではwith-redefsを使用し、最後の手段として、宣言されていない制御できない変数の動作を動的に変更します^:dynamic(その後は注意して使用してください)。

于 2013-04-01T17:33:52.540 に答える