1
(deftask test1 "first test task" [] (print "1") identity)
(deftask test2 "second test task" [] (print "2") identity)
(boot (comp (test1) (test2)))
=> 12nil
(boot (comp (fn [x] (print "1") identity) (fn [x] (print "2") identity)))
=> 21nil

タスクで使用compすると、実行順序は左から右になります。無名関数で使用するcompと、実行順序は右から左になります。この矛盾はどのように合理的ですか?

4

1 に答える 1

6

その違いの理由はcomp、ブート タスクで使用する場合、それらは構成される裸のロジックではなく、各ブート タスクは後で呼び出される関数を返し、その関数はそれに渡される別の関数をラップするためです (リングのように)ミドルウェア)。

単純な関数では、次のように機能します。

(comp inc dec)

以下を実行する関数を生成します。

(inc (dec n))

ブート タスクはリング ミドルウェアに似ています。各タスクは、パイプラインから次のハンドラーをラップする別の関数を返す関数です。そのように動作します (文字通りではなく、読みやすくするために単純化されています)。

(defn task1 []
  (fn [next-handler]
    (fn [fileset]
      (print 1) ;; do something in task1
      (next-handler fileset))) ;; and call wrapped handler

(defn task2 []
  (fn [next-handler]
    (fn [fileset]
      (print 2) ;; do something in task1
      (next-handler fileset)))) ;; and call wrapped handler

だからあなたがするとき:

(comp (task1) (task2))

そして、そのような構成されたタスクを実行すると、次のように機能します。

(fn [fileset1]
  (print 1)
  ((fn [fileset2]
     (print 2)
     (next-handler fileset2))
   fileset1))

関数によって生成された関数は、によって生成された(task2)関数に渡され、その関数によって生成された関数(task1)がラップされ(task2)ます (そして、印刷後にそれを呼び出します1)。

wikiでブート タスクの構造について詳しく読むことができます。ring middlewareについて読むのも役に立つかもしれません。

于 2016-04-17T07:46:01.337 に答える