2014-10-19 11 views
10

Poprzednio miałem api, które zawierało wiele funkcji, z których wszystkie oczekiwały mapy w bardzo szczególnym formacie. Kiedy dochodziłem do dokumentowania tego API, stwierdziłem, że w docstruktach każdej z tych funkcji powtarzałem "Mapa, z którą ta funkcja jest wywoływana, musi mieć taki i taki format, a to pole mapy oznacza takie i takie . "Dokumentacja rekordów w clojure

Więc pomyślałem, że lepiej byłoby, gdyby te funkcje pobrały płytę i żebym mógł zamiast tego udokumentować nagranie. Jednak nie wydaje się możliwe dokumentowanie rekordów, przynajmniej w jakikolwiek sposób interpretowane przez makro lub Marginalia.

Zaproponowane rozwiązanie here to "po prostu dodaj: klucz do dokumentu w meta rekordu".

Próbowałem (defrecord ^{:doc "Here is some documentation"} MyRecord [field1 field2]), ale makroekspanding sugeruje, że nie ma żadnego efektu. Również defrecord zwraca instancję java.lang.class, która nie implementuje IMeta, więc nie jestem pewien, czy możemy podać jej metadane?

  • Jak powinny być udokumentowane zapisy?
  • Czy zapisy są tutaj odpowiednim rozwiązaniem?
+0

Jeśli będziesz czytać dalej w tym wątku, zobaczysz, że dodanie klucza: doc do metadanych rekordu nie będzie działać. Zauważ, że możesz dodać ciąg dokumentu do protokołu. – user100464

+0

, ale [to] (http: // stackoverflow.com/questions/6627020/combining-clojure-defprotocol-and-defrecord) odpowiedź przepełnienia stosu zalecana jest przeciwko pisaniu protokołów, które są implementowane tylko przez jeden rekord, co prawdopodobnie nastąpi. –

+0

Jednym z rozwiązań jest biblioteka podobna do ['prismatic/schema'] (https://github.com/Prismatic/schema), która pozwala określić rodzaj akceptowanych danych, a także umożliwia weryfikację podanych argumentów. – noisesmith

Odpowiedz

2

TL; DR: Niestety nie można.

Z docs:

Symbole i zbiory metadanych wsparcie

Podczas korzystania defrecord jesteś rzeczywiście tworzenie klasy Java. Ponieważ klasy nie są ani symbolami, ani Clojure, nie możesz do nich dołączać dokumentacji.

bardziej szczegółowe wyjaśnienie

Poniższa sesja REPL pokazuje, dlaczego jej nie możliwe do dołączania metadanych do ewidencji.

user=> (defrecord A [a b]) 
#<[email protected] user.A> 
user=> (meta A) ;; <= A contains no metadata 
nil 

Ważne jest, aby zauważyć, że A jest regularną klasą języka Java. Jeśli spróbujesz ustawić metadanych dla dostaniesz ciekawą błąd

user=> (with-meta A {:doc "Hello"}) 

ClassCastException java.lang.Class cannot be cast to clojure.lang.IObj 

Podobno z-meta oczekuje clojure.lang.IObj. Od java.lang.Class jest konstruktem Javaland, to wyraźnie nie wie nic o clojure.lang.IObj.

Weźmy spojrzeć teraz na kod źródłowy dla with-meta

user=> (source with-meta) 
(def 
^{:arglists '([^clojure.lang.IObj obj m]) 
    :doc "Returns an object of the same type and value as obj, with 
    map m as its metadata." 
    :added "1.0" 
    :static true} 
with-meta (fn ^:static with-meta [^clojure.lang.IObj x m] 
      (. x (withMeta m)))) 

Jak widać, metoda ta spodziewa x mieć withMeta przedmiot, który rejestruje wyraźnie nie mają.