Clojure风格,像 - >与doto语义?

时间:2014-11-27 00:11:14

标签: clojure

我开始使用clojure来测试java库。所以我的问题更多"这样做的方法是什么"。

我有很多代码如下所示

...
 (with-open [fs (create-filesystem)]
    (let [root (.getFile fs path)]
       (is (.isDirectory root))
       (is (.isComplete root)))
    (let [suc (.getFile fs (str path "/_SUCCESS"))]
       (is (.isFile suc))
       (is (.isComplete suc))))

由于这是一个java对象,我需要在对象上验证一组属性是否为true。我知道doto会让我做像

这样的事情
(doto (.getFile fs path)
  (.setPath path2)
  (.setName name2))

和 - >将让我有一个部分函数列表,并让每个结果通过每个函数。一直在想像 - >但不断传递像doto这样的对象会对这些测试有所帮助。像这样的事情是一个很好的方法,或者我不是真的这样做的clojure方式?

谢谢你的时间!

4 个答案:

答案 0 :(得分:1)

您可以使用doto

(doto (.getFile fs path) (.setPath path2) (.setPath name2))

答案 1 :(得分:1)

您可以了解其他线程宏,例如cond->as->some->等..." Clojure方式"目的

没有宏可以完全满足您的需求。只有..doto是特定于对象的宏。

因为你的问题更多" Clojure方式"我推荐这个:

https://github.com/bbatsov/clojure-style-guide

答案 2 :(得分:0)

是的,您可以将.. macro用于带有线程语义的java互操作。

示例:

  <body ng-app="App">
    <h1>Hello Plunker!</h1>
    <div ng-controller="PageController as page">
      <button ng-click="page.open()">Open pane</button>
      <button ng-click="page.close('Closed from page')">Close pane</button>
    </div>
    <div pane></div>
  </body>

答案 3 :(得分:0)

使用let一样没有问题;它是一个非常直接和明确的实现你想做的事情。我认为这是最好的方法:)

但是,检查如何使用内置宏的Clojure来实现这一目标很有意思:

(doto (.getFile fs path)
  (-> (.isDirectory) (is))
  (-> (.isComplete) (is)))

doto的特殊之处在于它传播初始值。它采用后续表单并将初始值插入表单的第二个位置。

->允许您在内部排列表单...这意味着您可以将其与doto结合使用,以便初始值穿过您想要在其上执行的任何表单层。

现在doto->是宏,所以语法可能有点令人困惑......如果您更喜欢使用函数,那么juxt可以方便地调用多个函数:

((juxt #(is (.isDirectory %)) #(is (.isComplete))) (.getFile fs path))

但是对于这种情况来说这很难看:)。

回到原来的问题,你当然也可以用宏创建自己的语法......我在这里描述了一种方法:http://timothypratley.blogspot.pt/2016/05/composing-test-assertions-in-pipeline.html以方便的方式链接多个断言。

我认为你所描述的例子坚持使用let形式是最好的方式,因为它最明显......这里展示了其他形式以讨论可用的选项,其中一些可能适用于其他情况。