2017-12-01 5 views
0

나는 그것을하는 함수에 대한 호출을 리다이렉트하는 매크로를 쓰려고한다. 게시 된 모든 함수를 최상위 clj 파일로 수집하는 방법입니다. https://martinfowler.com/bliki/PublishedInterface.htmlCopy : arglists in clojure def

doc 문자열과 arglists를 복사하려고하는데, docstring은 잘 동작하지만 argslists는 작동하지 않습니다. 내가 뭘 놓치고 있니? 내가 대신 주석 회선을 사용하는 경우

(defmacro idef 
    [fname] 
    (let [sym (symbol (str "clojure.core/" fname)) 
     metas (meta (find-var sym)) 
     arglists (:arglists metas) 
     doc (:doc metas)] 
    ;;`(def ~(with-meta fname {:doc doc :arglists arglists})) 
    `(def ~(with-meta fname {:doc doc}) 
     ~sym))) 

(idef inc) 

, 나는이 그냥 네임 스페이스 Clojure의 코어에 하드 코드 샘플입니다

CompilerException clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentVector, compiling:(interface.clj:22:1) 

얻을.

이 질문은 정말 유사하지만 내가 복사 아무 문제가 없다 참조 : 문서의 일부를 특별한 약에 무엇 : arglists

Help me write a Clojure macro which automatically adds metadata to a function definition

답변

0

arglists 본질적으로 목록이기 때문에 당신은 그 오류를 얻고있다 ~으로 연결하면이 목록이 평가됩니다.

내가 예와 함께 설명 보자

user> (:arglists (meta #'clojure.core/inc)) 
([x]) 

당신이 당신의 매크로 내에서 ~(with-meta fname {:doc doc :arglists arglists})을하려고 당신이 arglists 기호에 바인딩 그대로 평가하는 형태입니다. 그래서 inc의 경우에 당신은 기본적으로이 작업을 수행하려고 : 당신이 점점 오류를보고

user> ([x]) 
ArityException Wrong number of args (0) passed to: PersistentVector clojure.lang.AFn.throwArity (AFn.java:429) 

합니다.

이 문제를 방지하려면 arglists 양식을 평가하지 않아야합니다. 이를 달성하는 방법 중 하나는 quote 전화 내에 넣어하는 것입니다

(defmacro idef 
    [fname] 
    (let [sym (symbol (str "clojure.core/" fname)) 
     metas (meta (find-var sym)) 
     arglists (:arglists metas) 
     doc (:doc metas)] 
    `(def ~(with-meta fname {:doc doc :arglists `(quote ~arglists)}) ~sym))) 
+0

그런 뭔가를 시도,하지만 난 역 인용 부호 안에 역 인용 부호를 가질 수 있습니다 몰랐어요. 감사! – mattias