【发布时间】:2017-03-25 14:29:55
【问题描述】:
我面临以下问题。我正在尝试在 hapi-fhir api 之上构建一个函数(宏)
function (macro) on topo of hapi-fhir api
(defmacro search-patient-resource
"This macro searches for a specified resource based on the
Patient Id"
[res id json?]
(let [tmp (symbol res)]
(if json?
`(. (. (. (. (. (. @restful-client search) (forResource ~(symbol res))) encodedJson) (where (. (. ~(resolve tmp) PATIENT)
(hasId (str ~id))))) (returnBundle Bundle)) execute)
)))
此宏在执行类似操作时起作用
(let [id 10465]
(search-patient-resource "Observation" id true))
=>#object[ca.uhn.fhir.model.dstu2.resource.Bundle 0x520a3cc9 "Bundle[id=Bundle/9ca62ae1-82af-488f-a166-5b014f45886e]"]
但不是在我这样做的时候
(let [id 10465 res "Observation"]
(search-patient-resource "Observation" id true))
=> CompilerException java.lang.NullPointerException, compiling:(apycare_emrspp/hapi_fhir_helper.clj:122:1)
我当然不能写(符号~res),因为那时读者会评估 (符号“观察”)在编译时,我得到
CompilerException java.lang.IllegalArgumentException: No matching method found: forResource for class ca.uhn.fhir.rest.client.GenericCl
ient$SearchInternal, compiling:(apycare_emrspp/hapi_fhir_helper.clj:122:1)
也没有
(resolve (symbol ~res)
也没有
(resolve ~(symbol re)
工作。
原来的java代码是这样的
FhirContext ctx = FhirContext.forDstu2();
String serverBase = "fhirtest.uhn.ca/baseDstu2";
IGenericClient client = ctx.newRestfulGenericClient(serverBase);
Bundle results = client .search() .forResource(Observation.class)
.where(Observation.PATIENT.hasId("1234"))
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.execute();
我所做的是尝试拨打电话
client
.search()
.forResource(another-resource.class)
.where(another-resource.PATIENT.hasId(another-id))
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.execute();
【问题讨论】:
-
我不明白你为什么要把它写成一个宏。看来你可以把它写成一个函数来避免这个问题。
-
怎么样?我试图把它写成一个函数,但是如何在没有 clojure 编译器抱怨的情况下传递任意方法名称?例如,假设我想通过 [Observation] 来调用 (.resource Observation)。如果我将它作为字符串传递,那么 (.resource (symbol "Observation)) 将不起作用,除非通过宏从列表中扩展。
-
请说明它的工作方式。
-
传递一个字符串和Id作为参数,该字符串必须转换为同名的java方法并被调用。这有效,但在我预定义字符串时无效。那就是当我通过“观察”时,我将 (forResource ~(symbol res)) 转换为 (forResource Observation) ,但如果我这样做 (def st "Observation") 那么我得到 (forResource st)。
-
我试图创建一个函数来从字符串创建符号,但它不起作用
标签: clojure macros clojure-java-interop