我正在尝试与Luminus建立一个网站,以便学习一些Clojure。我有多年的必要经验,但现在只进入函数式编程。现在,我正在尝试process a signed_request object from Facebook。
根据网站我必须:
如果我使用命令式语言这样做,这真的很直截了当,但在功能方法方面我很无能为力。现在我只知道如何将字符串拆分为2个字符串的向量:
(defn parse-request [signed_request]
((clojure.string/split signed_request #"\.")
))
(defn redirect-page [signed_request]
(layout/render "redirect.html"
{:parsed_request parse-request(signed_request)}))
(defroutes home-routes
(GET "/" [] (home-page))
(POST "/redirect" [signed_request] (redirect-page signed_request)))
当服务器收到POST请求时,重定向页面运行,然后它接受signed_request并将其传递给解析请求函数。解决这个问题的功能方法是什么?
答案 0 :(得分:1)
我认为你的问题的基本答案是函数式编程更多地是关于输入和输出(考虑数学函数),而命令式编程往往更多地关注副作用和可变数据。而不是思考,"我需要做什么?",思考,"我的目标是什么样的数据结构,以及我如何定义它?"你也可以有副作用(比如打印),但通常你会编写带有参数并返回内容的纯函数。
Destructuring是Clojure中一个非常宝贵的工具,它在这里会派上用场。您希望使用clojure.string/split
将字符串拆分为两个字符串,然后使用其中一个字符串和其他字符串执行某些操作。您可以使用let
绑定为每个字符串指定名称,如下所示:
(let [[str1 str2] (clojure.string/split signed-request #"\.")]
(do-stuff-with-str1-and-str2))
我对这个具体问题并不太熟悉,但根据你列出的3个步骤,听起来你会得到2个结果,每个字符串一个。所以,也许你应该专注于编写一个返回包含2个结果的向量的函数,如下所示:
(defn process-signed-request [signed-request]
(let [[str1 str2] (clojure.string/split signed-request #"\.")]
[(compare-fn (decode-with-base-64 str1) secret)
(decode-with-json (decode-with-base-64 str2))]))
请注意,以上是部分伪代码 - 您需要将compare-fn
,decode-with-base-64
,decode-with-json
和secret
替换为代表这些内容的实际代码 - 或者你可以保持原样并只是实现这些功能,以便compare-fn
,decode-with-base-64
和decode-with-json
引用你编写的实际功能。这是函数式编程中的常用方法 - 编写一个简短的高级函数来定义问题的解决方案,然后返回并编写它使用的辅助函数。
顺便说一句,还有其他几种方法可以编写(decode-with-json (decode-with-base-64 str2))
部分:
((comp decode-with-json decode-with-base-64) str2)
(-> str2 decode-with-base-64 decode-with-json)
我经常发现第二种方法,使用线程宏(->
或->>
),当我知道对象需要做的事情的顺序时,我会想要代码直观地阅读。我觉得它更容易阅读,例如"取str2
,用base 64解码,然后用JSON再次解码。"
另外,这只是一个挑剔的事情,但是当你在Clojure中进行编码时要注意括号的顺序。您现在拥有代码的方式,括号应如下所示:
(defn parse-request [signed_request]
(clojure.string/split signed_request #"\."))
(defn redirect-page [signed_request]
(layout/render "redirect.html"
{:parsed_request (parse-request signed_request)}))
如果您有很多必要的经验,那么您可能会在fn(x)
语法中根深蒂固地插入,而不是Clojure使用的(fn x)
Lisp语法。
虽然我在挑剔,但在Clojure中使用连字符代替下划线进行符号命名是惯用的。因此,我会将signed_request
和:parsed_request
重命名为signed-request
和:parsed-request
。
希望有所帮助!