Commits

taka2ru committed 4aa40ad

initial import

Comments (0)

Files changed (4)

+# scope
+
+FIXME: write description
+
+## Usage
+
+FIXME: write
+
+## License
+
+Copyright (C) 2012 FIXME
+
+Distributed under the Eclipse Public License, the same as Clojure.
+(defproject org.clojars.taka2ru/scope "0.0.1-SNAPSHOT"
+  :description "Resource Scope looking ahead"
+  :dependencies [[org.clojure/clojure "1.3.0"]])

src/scope/core.clj

+(ns scope.core)
+
+(def ^:dynamic *scope* nil)
+
+(defn run-scope-actions []
+  (let [failed (= (first *scope*) :failed)
+        entries (if failed (rest *scope*) *scope*)]
+    (doseq [e entries]
+        (let [cause (first e)
+              action (second e)]
+          (when (or (= cause :exits)
+                    (and (= cause :fails) failed)
+                    (and (= cause :succeeds) (not failed)))
+            (action))))))
+
+(defmacro scope
+  "Creates a scope for use with when-scope."
+  [& body]
+  `(binding [*scope* (list)]
+     (try
+      ~@body
+      (catch Throwable t#
+        (set! *scope* (conj *scope* :failed))
+        (throw t#))
+      (finally
+       (run-scope-actions)))))
+
+(defmacro when-scope 
+  "Causes a body of expressions to be executed at the termination of
+  the nearest dynamically enclosing scope (created with scope). If no
+  scope is in effect, throws IllegalStateException. Cause must be one of:
+
+  :exits - will run unconditionally on scope exit
+  :fails - will run only if scope exits due to an exception
+  :succeeds - will run only if scope exits normally"
+
+  [cause & body]
+  `(do
+     (when-not *scope*
+       (throw (IllegalStateException. "No scope in effect")))
+     (set! *scope* (conj *scope* [~cause (fn [] ~@body)]))))
+

test/scope/test/core.clj

+(ns scope.test.core
+  (:use [scope.core])
+  (:use [clojure.test]))
+
+(deftest replace-me ;; FIXME: write
+  (is false "No tests have been written."))