2012-10-17 23 views
5

Używam biblioteki innej firmy (clj-msgpack) i chcę rozszerzyć protokół dla typu, który biblioteka udostępnia również dla programu obsługi.Rozszerzanie protokołu udostępnianego przez bibliotekę bez wpływu na innych użytkowników.

Sam w sobie jest to dość proste - ale czy jest jakiś sposób na zrobienie tego, co nie miałoby wpływu na innych użytkowników tej biblioteki działającej w tej samej maszynie JVM? Coś podobnego do dynamicznego wiązania var (działającego tylko pod danym punktem na stosie) byłoby idealne.

W tej chwili robię bezwarunkowe zastąpienie, ale przy użyciu dynamicznego var, aby umożliwić moje zmodyfikowane zachowanie; to jednak wydaje mi się zbyt wiele jak łatanie małp dla mojej wygody.

Dla ciekawskich, The (dopuszczone obrzydliwością) Kładę na miejsce następująca:

(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)))) 
+0

Widelec, dodać funkcję trzeba, a przesłać żądanie pobrania; ^) – noahlz

+0

@noahz Wysłałem bilet z kodem. Niezależnie od tego, czy ta funkcja jest pożądana, to bardzo wątpliwa rzecz - nie jestem pewien, czy zaakceptowałbym ją, gdybym była nimi. –

+0

Zrobiłem ten komentarz tounge-cheek (z powodów, o których wspomniałeś), ale z drugiej strony ... API powinny być "otwarte dla rozszerzenia, zamknięte dla modyfikacji". – noahlz

Odpowiedz

1

po namyśle widzę dwa podstawowe approches (z których jeden dostaję od ciebie):

Wiązanie dynamiczne (tak jak teraz to robisz):

Niektórzy narzekają, że wiązanie dynamiczne ma znaczenie dla większości najbardziej niespodzianki; "co? zachowuje się w ten sposób tylko wtedy, gdy jest wywoływane z tego miejsca?". Chociaż osobiście nie uważam tego za coś złego (tm), niektórzy ludzie to robią. W tym przypadku jest dokładnie dopasowany do twojego pragnienia i tak długo, jak masz jeden punkt, w którym zdecydujesz, czy chcesz używać słów-kluczy, to powinno działać. Jeśli dodasz drugi punkt, który je odmieni i ścieżkę kodu, która przecina dwie dobrze ... twoją na własną rękę. Ale hej, działający kod ma swoje zalety.

Dziedziczenie:

styl good'ol java lub stosując dodatek hoc heirarchies Clojure mogłaby rozszerzyć rodzaj obiektu, który przechodzi wokół zostać keywordized-string-widgewhatzit który rozciąga widgewhatzit i dodać nowy program obsługi dla twoja konkretna podklasa:. Działa to tylko w niektórych przypadkach i wymusza inny styl obiektu w pozostałej części projektu. Niektórzy sprytni ludzie będą również twierdzić, że nadal podąża za głównym zaskoczeniem, ponieważ typ obiektów będzie inny, gdy zostanie wywołany przez inną ścieżkę kodu.


Osobiście pójdę z istniejącego rozwiązania, chyba że można zmienić cały swój program, aby używać słów kluczowych zamiast strun (co byłoby oczywiście mój pierwszy (potencjalnie kontrowersyjne) wybór)

+0

Nie mogę wykonać podejścia do implementacji protokołu opartego na podklasie, ponieważ obiekt, który jest obsługiwany, jest generowany przez samą bibliotekę (właściwie przez bibliotekę _it_ używa). W przeciwnym razie moje preferencje byłyby zupełnie inne, ponieważ są całkowicie pozbawione szacunku dla innych użytkowników. –

+0

... przy okazji, głównym powodem, dla którego nie podoba mi się obecne podejście, jest to, że modyfikuje kod biblioteki. Tak, nowe zachowanie powinno być przełączane przez dynamiczne powiązanie ... ale jeśli w górę dostrojenia oryginalna ścieżka kodowa i nie przyjmuję tej funkcji do mojej nadpisanej wersji, wszyscy użytkownicy biblioteki w danym środowisku Clojure tracą wcześniej zmienić, nie tylko mój własny kod. Byłem wystarczająco wypalony przez łatanie małp w światach Ruby i Pythona, aby być bardzo, bardzo ostrożnym, aby go tutaj zatwierdzić. –

+0

Teraz, kiedy ją opublikowałeś, ktoś podąży za twoim przykładem ;-) Sięgasz po inną bibliotekę i przekręcasz jej bity, więc prawdopodobnie istnieje pewna granica tego, jak czyste może to być: -/ –

Powiązane problemy