Clojure 使用get参数作为函数名
这是我的clojure戒指处理器Clojure 使用get参数作为函数名,clojure,ring,Clojure,Ring,这是我的clojure戒指处理器 (defn handler [req] (let [distr (get-in req [:query-params "dist"])] (def sortie (describe (eval ((resolve (symbol distr)) 1 3)) 0.5 0.25 3)) {:status 200 :headers {"Content-Type" "text/html"}
(defn handler [req]
(let [distr (get-in req [:query-params "dist"])]
(def sortie (describe (eval ((resolve (symbol distr)) 1 3))
0.5 0.25 3))
{:status 200
:headers {"Content-Type" "text/html"}
:body (str "<p>" (print-str sortie) "<p>")}
))
(def app
(-> #'handler
(ring.middleware.stacktrace/wrap-stacktrace)
(wrap-spy)
(wrap-params)
))
我想用它作为函数名。
整体
(eval ((resolve (symbol distr)) 1 3))
返回一个映射
当我用字符串替换Disr时,它可以按需要工作
=> (eval ((resolve (symbol "gaussian-dist")) 1 3))
{:Distribution :actuarial.distributions/Gaussian, :Parameters {:sigma 3, :mu 1}}
编辑:
这就是我最终解决问题的原因:
再次感谢,我是Clojure的初学者
我用一个宏完成了
(defmacro get-map [map name]
`(get ~map ~name))
(defn handler [req]
(let [distr-name (get-in req [:query-params "dist"])
distr-map ((get-map distributions-map distr-name) 1 3)
sortie (describe distr-map 0.5 0.25 3)
]
{:status 200
:headers {"Content-Type" "text/html"}
:body (str "<p>" sortie "<p>")}))
(defmacro获取映射[映射名称]
`(获取~map~名称))
(defn处理程序[req]
(让[Disr name(获取请求[:查询参数“dist”]))
分发地图((获取地图分发地图分发名称)1 3)
出动架次(描述分布图0.5 0.25 3)
]
{:现状200
:标题{“内容类型”“文本/html”}
:身体(str“”架次“”))
从安全性和可维护性的角度来看,让Internet将名称空间中的任何符号作为函数调用似乎有点冒险,因此我的想法是:
以从查询参数字符串到函数的映射形式,准备用户应该能够请求的函数的白名单
(def distributions {"gaussian-dist" gaussian-dist})
创建一个默认函数,该函数要么生成错误消息,要么只是选择一些默认分布。获取查询时,只需使用
get
在distributions
中查找所需的函数,以及处理未找到查询字符串情况的默认函数
(let [distr (get-in req [:query-params "dist"])
sortie ((get distributions distr default-fn) 1 3)]
对每个请求执行
def
类似于出击的var也有点冒险,因为这会让你面临竞争条件。这就是为什么也让这个名字看起来更自然的原因,除非处理程序有比我在这里看到的更多的东西。您还可以使用(def^:dynamic*sortie*)
和binding
执行您想要的操作,这将不同线程的绑定彼此隔离,以防止出现这种情况。看起来很可能distr
的值与预期不符,您是否可以输入println,或者以其他方式检查它,并包括输出?请勿在函数中使用def<代码>出击
在使用前可以被另一个请求替换。这个宏并没有做任何你不能用函数做的事情,更简单的说:(defn get map[map name](get map name))
,或者实际上是(def get map get)
。在请求处理程序中定义符号并不是“有点风险”,而是完全错误的。变量是全局可访问的可变状态,没有并发机制。
(let [distr (get-in req [:query-params "dist"])
sortie ((get distributions distr default-fn) 1 3)]