From 96e372cddcb61b056c41e2f7dcbca47571bf4530 Mon Sep 17 00:00:00 2001 From: Mariano Guerra Date: Wed, 9 Jan 2013 16:50:59 +0100 Subject: [PATCH] convert clojure functions to rhino functions in to-js --- README.rest | 23 +++++++++++++++++++++++ src/clj_rhino.clj | 23 ++++++++++++++--------- test/clj_rhino/core_test.clj | 13 ++++++++++--- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/README.rest b/README.rest index 17fb43a..e5361f6 100644 --- a/README.rest +++ b/README.rest @@ -98,6 +98,29 @@ exposing clojure functions to rhino:: user=> (js/eval scope "add(1, 2)") 3.0 +exposing objects with functions:: + + + user=> (require '[clj-rhino :as js]) + nil + + user=> (defn add [ctx scope this [a b]] (+ a b)) + #'user/add + + user=> (defn mul [ctx scope this [a b]] (* a b)) + #'user/mul + + user=> (def scope (js/new-safe-scope)) + #'user/scope + + user=> (def api {:add add :multiply mul}) + #'user/api + + user=> (js/with-context (fn [ctx] + #_=> (js/set! scope "api" (js/to-js api scope ctx)) + #_=> (js/eval scope "api.add(1, 2) + api.multiply(2, 3)"))) + 9.0 + license? -------- diff --git a/src/clj_rhino.clj b/src/clj_rhino.clj index 8be255d..4236146 100644 --- a/src/clj_rhino.clj +++ b/src/clj_rhino.clj @@ -39,6 +39,16 @@ (to-js (seq obj) scope ctx) (throw (Exception. (str "Don't know how to convert to rhino " (class obj)))))) +(defn make-fn [fun] + "return an object that can be used as a function in rhino, + fun must receive the following arguments [ctx scope this args] + args will be passed through from-js before calling fun and the result + through to-js" + + (proxy [BaseFunction] [] + (call [ctx scope this args] + (to-js (fun ctx scope this (from-js args)) scope ctx)))) + (extend nil RhinoConvertible {:-to-rhino return-self}) (extend java.lang.Boolean RhinoConvertible {:-to-rhino return-self}) @@ -58,6 +68,10 @@ (extend java.util.Map RhinoConvertible {:-to-rhino to-js-object}) (extend java.util.Collection RhinoConvertible {:-to-rhino to-js-array}) +;; Functions +(extend clojure.lang.Fn RhinoConvertible {:-to-rhino (fn [obj scope ctx] + (make-fn obj))}) + ;; Maybe a Java array, otherwise fail (extend java.lang.Object RhinoConvertible {:-to-rhino to-js-generic}) @@ -200,12 +214,3 @@ (or filename "") (or line-number 1) sec-domain)))) -(defn make-fn [fun] - "return an object that can be used as a function in rhino, - fun must receive the following arguments [ctx scope this args] - args will be passed through from-js before calling fun and the result - through to-js" - - (proxy [BaseFunction] [] - (call [ctx scope this args] - (to-js (fun ctx scope this (from-js args)) scope ctx)))) diff --git a/test/clj_rhino/core_test.clj b/test/clj_rhino/core_test.clj index f05e288..71c63b5 100644 --- a/test/clj_rhino/core_test.clj +++ b/test/clj_rhino/core_test.clj @@ -161,9 +161,16 @@ (testing "native clojure functions can be added" (js/with-context (fn [ctx] - (let [scope (js/new-safe-scope)] - (js/set! scope "add" (js/make-fn (fn [ctx scope this [a b]] (+ a b)))) - (is (= (js/eval scope "add(1, 2)") 3.0)))))) + (let [scope (js/new-safe-scope) + add (fn [ctx scope this [a b]] (+ a b)) + multiply (fn [ctx scope this [a b]] (* a b)) + api {:add add :multiply multiply}] + (js/set! scope "add" (js/make-fn add)) + (js/set! scope "api" (js/to-js api scope ctx)) + + (is (= (js/eval scope "add(1, 2)") 3.0)) + (is (= (js/eval scope "api.add(1, 2) + api.multiply(2, 3)") 9.0)) + )))) )