Skip to content

Instantly share code, notes, and snippets.

@Kaali
Created July 21, 2010 06:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kaali/484140 to your computer and use it in GitHub Desktop.
Save Kaali/484140 to your computer and use it in GitHub Desktop.
(defn validator [param forms]
(remove nil?
(map (fn [[f s]] (when-not (f param) s)) forms)))
(defn- validator-wrapper [forms]
`(fn [param#] (validator param# ~forms)))
(defn form* [forms]
(apply merge
(map (fn [[k v]] {k (validator-wrapper v)}) (apply array-map forms))))
(defmacro defform
"Define a web form for validation"
[name & forms]
(let [validators (form* forms)]
`(defn ~name [params#]
(apply merge
(map (fn [[k# v#]] {k# ((k# ~validators) v#)}) params#)))))
(defn required [param] (not (nil? param)))
(defn minimum-length [minlen]
(fn [param] (>= (count param) minlen)))
(defform test-form
:login [[required "Login is required"]]
:password [[required "Password is required"]
[(minimum-length 5) "Password should be longer than 5 chars"]])
@Kaali
Copy link
Author

Kaali commented Jul 21, 2010

The test-form defined doesn't work:

(test-form {:login "Foo" :password "Bar"})

which results in:

No message.
  [Thrown class java.lang.ExceptionInInitializerError]

Restarts:
 0: [QUIT] Quit to the SLIME top level
 1: [CAUSE1] Invoke debugger on cause  java.lang.IllegalArgumentException: No matching ctor found for class clj_webforms.core$transform$fn__3660 [Thrown class java.lang.RuntimeException]
 2: [CAUSE2] Invoke debugger on cause   No matching ctor found for class clj_webforms.core$transform$fn__3660 [Thrown class java.lang.IllegalArgumentException]

Backtrace:
  0: clj_webforms.core$test_form.invoke(NO_SOURCE_FILE:1)
  1: clj_webforms.core$eval3701.invoke(NO_SOURCE_FILE:1)
  2: clojure.lang.Compiler.eval(Compiler.java:5419)
  3: clojure.lang.Compiler.eval(Compiler.java:5386)
  4: clojure.core$eval.invoke(core.clj:2382)
  5: swank.commands.basic$eval_region.invoke(basic.clj:47)
  6: swank.commands.basic$eval_region.invoke(basic.clj:37)
  7: swank.commands.basic$eval805$listener_eval__806.invoke(basic.clj:71)
  8: clojure.lang.Var.invoke(Var.java:365)
  9: clj_webforms.core$eval3699.invoke(NO_SOURCE_FILE)
 10: clojure.lang.Compiler.eval(Compiler.java:5419)
 11: clojure.lang.Compiler.eval(Compiler.java:5386)
 12: clojure.core$eval.invoke(core.clj:2382)
 13: swank.core$eval_in_emacs_package.invoke(core.clj:94)
 14: swank.core$eval_for_emacs.invoke(core.clj:241)
 15: clojure.lang.Var.invoke(Var.java:373)
 16: clojure.lang.AFn.applyToHelper(AFn.java:169)
 17: clojure.lang.Var.applyTo(Var.java:482)
 18: clojure.core$apply.invoke(core.clj:540)
 19: swank.core$eval_from_control.invoke(core.clj:101)
 20: swank.core$eval_loop.invoke(core.clj:106)
 21: swank.core$spawn_repl_thread$fn__487$fn__488.invoke(core.clj:311)
 22: clojure.lang.AFn.applyToHelper(AFn.java:159)
 23: clojure.lang.AFn.applyTo(AFn.java:151)
 24: clojure.core$apply.invoke(core.clj:540)
 25: swank.core$spawn_repl_thread$fn__487.doInvoke(core.clj:308)
 26: clojure.lang.RestFn.invoke(RestFn.java:398)
 27: clojure.lang.AFn.run(AFn.java:24)
 28: java.lang.Thread.run(Thread.java:637)

@Kaali
Copy link
Author

Kaali commented Jul 21, 2010

The newest version works, the problem was with the scope of Fns. I guess.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment