2012-08-09 3 views
2

작업을 위해 표준 약식 형식 (약물 부작용을보고하는 데 사용되는 형식)을 가장 간결한 방식으로 설명하고 싶습니다. (대략, 딸꾹질을 통해 나중에 그것을 렌더링하는하지만 딸꾹질 구조로 직접 작성하지 않는 이유뿐만 아니라, 그건) 예를 들어또 다른 컬렉션 내부에 스플 라이스

을, 설명의 일부는 다음과 같습니다

{"reportertitle" [:one-of "Dr" "Pr" "Mrs" "Mr"] ; the reporter is usually the physician 
"reportergivenname" :text 
"reporterfamilyname" :text 
"reporterorganization" :text 
"reporterdepartment" :text 
.... 
"literaturereference" :text 
"studyname" :text 
....} 

키 표준 이름이지만 변경할 수는 없지만 물건을 쉽게 인수 분해 할 수 있기를 바랍니다. 예를 들어 접두사 "리포터"가지도 전체에서 많이 사용되는 경우이를 분해 할 수 있습니다. 예를 들어 :

{ (prefix "reporter" 
    "title" [:one-of "Dr" "Pr" "Mrs" "Mr"] 
    "givenname" :text 
    "familyname" :text 
    "organization" :text 
    "department" :text) 
    ..... 
    "literaturereference" :text 
    "studyname" :text 
    ....} 

하지만이 기능은 작동하지 않습니다. annot "integrate"(스플 라이스, 나는 올바른 용어라고 믿는다)는 '접두어'의 결과이다. 바깥 쪽 맵 내부의 함수 나 매크로 일 것이다.

높은 수준의 선언성/간결성을 유지하면서이를 달성 할 수있는 해결책이 있습니까?

덕분에), (나는 거의 모든 디자인 제안을 환영합니다, Clojure의에 새로 온 사람으로)

(전체 형태는 거대하고 비 개발자가 읽을 수 있습니다)!

답변

1

매크로가 eval에 결과를 외부 표현으로 이어 붙일 수 없다는 것이 옳습니다. 그 주위의 간단한 방법은 prefix 표현식을 인식하는 매크로에 전체 맵 정의를 래핑하고 결과 맵 정의 내에서 적절한 키 - 값 시퀀스로 변환하는 것입니다.

또한 단지 merge으로 서브맵을 접착하여 기능을 수행 할 수 있습니다 좀 더 자세한하지만 아마도 조금 더 읽을 수 있습니다

(defn pref-keys [p m] (apply hash-map (apply concat (for [[k v] m] [(str p k) v]))))) 

(merge 
    (pref-keys "reporter" 
     {"title" [...] 
     "givenname" :text 
     ...}) 
    {"literaturereference" :text 
     "studyname" :text}) 

.

편집 : 매크로가 (내부 또는 외부의) 매크로가 평가되기 전에지도 리터럴이 만들어집니다. 인수가 맵 리터럴 인 매크로는 결과적으로 맵을 생성 할 어떤 형식이 아닌 맵을 가져옵니다. 물론이지도의 키와 값은 평가되지 않은 형식이지만지도 자체는 적절한지도 (IPersistentMap)입니다. my-smart-macroprefix을 확장 할 수있는 기회를 가지고 전에

(my-smart-macro { (prefix "reporter" ...) }) 

가 실패합니다

는 특히이 문자 ​​그대로의 요구는 심지어 형태의 수, 그래서이를 포함하는 것을 의미한다. 반면에 이것은 성공할 것입니다 :

(another-macro { (/ 1 0) (/ 1 0) }) 

... 매크로는 입력 맵에서 유효하지 않은 산술 표현을 걸러냅니다.

즉,지도 리터럴을 매크로에 전달하지 않으려 고합니다.

+0

그래, 내 매크로를 좀 더 업스트림으로 불러야 할 것 같네. 컴파일시 clojure.zip 함수를 사용하여 '접두어'형식을 찾고 변경할 수 있습니까? 아니면 더 편리한 방법이 있습니까? 이제 여러분이 그것에 대해 이야기 했으므로, 매크로 arg 내부에 중첩 된 용어를 대체하는 것이 꽤 일반적 일 것입니다 (저는 Scheme에서 그런 것을 보았습니다). –

+0

나는'(접두사 "기자"bla-bla-bla) "를'["기자 "bla-bla-bla]로 바꿀 것을 제안 할 것이다. 이렇게하면 매크로를 작성할 필요가 없습니다 (대신 일반 함수를 작성할 수 있습니다). –

+0

@NikitaBeloglazov : 비 매크로 버전에 대한 제안에 따라 편집했습니다. –

0

사전에 나는이 대답이 당신이 찾고있는 것이 아닐 수도 있다고 말합니다. 그것은 당신의 데이터 구조를 완전히 바꿀 수있는 일을하는 방법 일 것입니다. 당신이 할 수있는 일이 아니라는 말을하는 것 같습니다.어쨌든, 나는 그것이 데이터 구조로 변경 될 것이라고 생각하기 때문에 제안하고 있습니다.

그래서, 여기에 내가 당신을 다시 구상 제안 방법은 데이터 :

내가 앞으로 여기에두고있어 두 가지 변화가 있습니다
{:reporter {:title "Dr, Pr, Mrs, or Mr here" 
      :given-name "text here" 
      :family-name "text here" 
      :organization "text here" 
      :department "text here" 
      ...} 
:literature-reference "text here" 
:study-name "text here" 
...} 

하나는 구조이고 다른 하나는 "화장품"입니다. 구조적인 것은 기자 관련 자료를 위해 거기에 또 다른지도를 중첩시키는 것입니다. 나는 이것이 개인적으로 데이터가 더 명확하게 보이며 접근하기가 쉽지 않다고 생각합니다. 액세스하려면 (get *data* "reportertitle")과 같은 것을 수행하는 대신 (assoc *data* "reportertitle" *new-title*)을 사용하여 새 버전을 만들어야합니다. 대신 (get-in *data* [:reporter :title])(assoc-in *data* [:reporter :title])이됩니다.

이러한 변경은 문자열 기반 키를 Clojure 키워드로 변경하는 것입니다. 필자가 제안한 주된 이유는 더 관용적이며 코드를 읽는 것이 잠재적으로 더 명확해진다는 것입니다. 키워드를 사용하는 이유에 대한 자세한 내용은 here 또는 here을 참조하십시오.

이제 실제로 미리 말한 모든 것을 실현합니다. 은 데이터 구성 방법과 키워드 이름이 변경되는 방식을 변경합니다. "키는 표준 이름이고 변경할 수는 없습니다"라고 말하면이 유형의 솔루션이 효과가 없을 것입니다. , 두 형식을 상호 변환 할 수 있습니다. 이 데이터를 어딘가에서 가져오고 이미 위와 같은 형식을 가지고 있다면 키워드 형식의 중첩 된지도 형식으로 변환하고 그 방식대로 유지하십시오. 그런 다음 실제로 출력되거나 사용되는 데이터를 내보낼 때 (또는 그것이 제공하는 최종 목적에 상관없이) 위에서 설명한대로 데이터를 다시 양식으로 변환합니다.

필자는 개인적으로 나는이 "상호 전환"아이디어를 전혀 좋아하지 않는다고 말해야한다. 나는 그것이 "코드"와 "데이터"라는 개념을 나눌 것이라고 생각한다. 이것은 데이터보다 코드가 "더 멋지게 느껴진다"고 생각할 때 그런 부끄러운 것처럼 보인다. 즉, 에 당신이에 좋게 들릴 경우를 대비하여 제안하고 있습니다.

+0

나는 귀하의 솔루션이 더 "clojurian"이 될 것이라고 동의합니다. 지금까지 내가 한 것은 다음과 같습니다. http://goo.gl/9JK2R 벡터로 전환 했으므로 다음을 유의하십시오. {} (기본적으로?)는 순서를 처리하지 않습니다 (그리고 순서를 지정할 수 있기를 원합니다. 필드가 표시되어야 함) "text"가 기본 필드 형식이어야합니다 (즉, 키가 항상 값을 가지는 것은 아닙니다). 그리고 마지막으로, 디스플레이 관련 "작업"을 지정할 수 있기를 원합니다 (예 : section은 div를 작성해야한다는 것을 나타내지 만 "div"는 넣지 않습니다. 왜냐하면 내가 말한 것처럼 해당 데이터로 HTML 생성). –