5

サードパーティ ライブラリ ( clj-msgpack ) を使用しており、ライブラリがハンドラーも提供するタイプのプロトコルを拡張したいと考えています。

これ自体は簡単ですが、同じ JVM 内で実行されているこのライブラリの他のユーザーに影響を与えずにこれを行う方法はありますか? 動的 var バインディングに似たもの (スタック上の特定のポイントでのみ有効になる) が理想的です。

現在、無条件のオーバーライドを行っていますが、動的変数を使用して変更された動作を有効にしています。ただし、これは私の快適さのために、モンキー パッチのように感じすぎます。

好奇心旺盛な人のために、私が導入している(認められた嫌悪感)は次のとおりです。

(in-ns 'clj-msgpack.core)

(def ^:dynamic *keywordize-strings*
  "Assume that any string starting with a colon should be unpacked to a keyword"
  false)

(extend-protocol Unwrapable
  RawValue
  (unwrap [o]
    (let [v (.getString o)]
      (if (and *keywordize-strings* (.startsWith v ":"))
        (keyword (.substring v 1))
        v))))
4

1 に答える 1

1

少し考えた後、私は2つの基本的なアプローチを見つけました(そのうちの1つはあなたから得たものです):

動的バインディング(現在行っているように):

動的バインディングがほとんどの驚きの原則に当てはまると不満を言う人もいます。「何? そこから呼び出されたときだけこのように動作しますか?」. 私は個人的にこれが悪いことだとは思っていませんが、そうする人もいます。この場合、それはあなたの欲求と正確に一致し、キーワード化された文字列が必要かどうかを決定する1つのポイントがある限り、これは機能するはずです. それらを元に戻す2番目のポイントと、2つをうまく交差させるコードパスを追加する場合...あなた自身で。しかし、作業コードにはメリットがあります。

継承:

良い Java スタイルまたは clojure のアドホック階層を使用して、渡しているオブジェクトのタイプを拡張して、widgewhatzit を拡張し、特定のサブクラスの新しいハンドラーを追加するkeywordized-string-widgewhatzit にすることができます。これは一部のケースでのみ機能し、デザインの残りの部分で異なるオブジェクト スタイルを強制します。一部の賢明な人々は、別のコード パスを介して呼び出されるとオブジェクトの型が異なるため、最も驚くべき原則に従っていると主張することもあります。


個人的には、文字列の代わりにキーワードを使用するようにプログラム全体を変更できない限り、既存のソリューションを使用します(もちろん、これは私の最初の(物議を醸す可能性のある)選択です)

于 2012-10-17T21:20:48.307 に答える