Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 使用get参数作为函数名_Clojure_Ring - Fatal编程技术网

Clojure 使用get参数作为函数名

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"}

这是我的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"}
     :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)]