2013-01-08 10:55:55 -05:00
|
|
|
clj-rhino
|
|
|
|
=========
|
|
|
|
|
|
|
|
a nice wrapper to handle rhino from clojure
|
|
|
|
|
|
|
|
who?
|
|
|
|
----
|
|
|
|
|
|
|
|
marianoguerra
|
|
|
|
|
|
|
|
why?
|
|
|
|
----
|
|
|
|
|
|
|
|
the java api for rhino is not really nice
|
|
|
|
|
|
|
|
how?
|
|
|
|
----
|
|
|
|
|
2013-01-09 09:40:27 -05:00
|
|
|
go to clojars page for instructions:
|
|
|
|
|
|
|
|
https://clojars.org/org.marianoguerra/clj-rhino
|
|
|
|
|
2013-01-08 11:02:40 -05:00
|
|
|
you can see the tests for some usage, here are some REPL examples::
|
2013-01-08 10:55:55 -05:00
|
|
|
|
|
|
|
user=> (require '[clj-rhino :as js])
|
|
|
|
nil
|
|
|
|
user=> (def sc (js/new-safe-scope))
|
|
|
|
#'user/sc
|
|
|
|
user=> (js/eval sc "1 + 1")
|
|
|
|
2
|
|
|
|
user=> (js/eval sc "a = 1 + 1")
|
|
|
|
2
|
|
|
|
user=> (js/get sc "a")
|
|
|
|
2
|
|
|
|
user=> (js/get sc "b")
|
|
|
|
#<UniqueTag org.mozilla.javascript.UniqueTag@172897f: NOT_FOUND>
|
|
|
|
user=> (js/undefined? (js/get sc "b"))
|
|
|
|
true
|
|
|
|
user=> (js/get sc "b" :w00t?)
|
|
|
|
:w00t?
|
|
|
|
user=> (js/defined? (js/get sc "b"))
|
|
|
|
false
|
|
|
|
user=> (js/set! sc "b" 42)
|
|
|
|
nil
|
|
|
|
user=> (js/defined? (js/get sc "b"))
|
|
|
|
true
|
|
|
|
user=> (js/get sc "b" :w00t?)
|
|
|
|
42
|
|
|
|
user=> (js/eval sc "a = {name: 'spongebob'}")
|
|
|
|
#<NativeObject [object Object]>
|
|
|
|
user=> (js/get-in sc [:a :name])
|
|
|
|
"spongebob"
|
|
|
|
user=> (js/get-in sc [:a :age])
|
|
|
|
#<UniqueTag org.mozilla.javascript.UniqueTag@172897f: NOT_FOUND>
|
|
|
|
user=> (js/get-in sc [:a :age] :dont-know)
|
|
|
|
:dont-know
|
|
|
|
user=> (def compiled-fun (js/compile-function sc "function (a, b) { return a + b; }" :filename "foo.js"))
|
|
|
|
#'user/compiled-fun
|
|
|
|
user=> (js/set! sc "add" compiled-fun)
|
|
|
|
nil
|
|
|
|
user=> (js/eval sc "add(1, 3)")
|
|
|
|
4.0
|
2013-01-09 09:13:09 -05:00
|
|
|
|
|
|
|
handy convertions::
|
|
|
|
|
|
|
|
user=> (def get-field (js/compile-function sc "function getField(obj, field) { return obj[field]; }"))
|
|
|
|
#'user/get-field
|
|
|
|
|
|
|
|
user=> (js/set! sc "getField" get-field)
|
|
|
|
nil
|
|
|
|
|
|
|
|
user=> (js/set! sc "obj" (js/with-context #(js/to-js {:name "spongebob"} sc %)))
|
|
|
|
nil
|
|
|
|
|
|
|
|
user=> (js/eval sc "getField(obj, 'name')")
|
|
|
|
"spongebob"
|
|
|
|
|
|
|
|
user=> (js/eval sc "o = {name: 'spongebob', friends: ['patrick', 'sandy']};")
|
|
|
|
#<NativeObject [object Object]>
|
|
|
|
|
|
|
|
user=> (js/from-js (js/eval sc "o = {name: 'spongebob', friends: ['patrick', 'sandy']};"))
|
|
|
|
{:friends ["patrick" "sandy"], :name "spongebob"}
|
2013-01-08 10:55:55 -05:00
|
|
|
|
2013-01-09 10:26:14 -05:00
|
|
|
exposing clojure functions to rhino::
|
|
|
|
|
|
|
|
user=> (require '[clj-rhino :as js])
|
|
|
|
nil
|
|
|
|
|
|
|
|
user=> (defn add [ctx scope this [a b]] (+ a b))
|
|
|
|
#'user/add
|
|
|
|
|
|
|
|
user=> (def scope (js/new-safe-scope))
|
|
|
|
#'user/scope
|
|
|
|
|
|
|
|
user=> (js/set! scope "add" (js/make-fn add))
|
|
|
|
nil
|
|
|
|
|
|
|
|
user=> (js/eval scope "add(1, 2)")
|
|
|
|
3.0
|
|
|
|
|
2013-01-09 10:50:59 -05:00
|
|
|
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
|
|
|
|
|
2013-01-09 11:38:50 -05:00
|
|
|
or if you don't need the internal parameters::
|
|
|
|
|
|
|
|
(js/with-context
|
|
|
|
(fn [ctx]
|
|
|
|
(let [scope (js/new-safe-scope)
|
|
|
|
add (fn [a b] (+ a b))]
|
|
|
|
|
|
|
|
(js/set! scope "add" (js/wrap-plain-fn add))
|
|
|
|
(js/eval scope "add(1, 2)") 3.0)))
|
|
|
|
|
2013-02-08 11:50:25 -05:00
|
|
|
execute code with timeout::
|
2013-02-07 10:49:05 -05:00
|
|
|
|
|
|
|
(def scope (js/new-safe-scope))
|
|
|
|
(js/eval-timeout scope "while (true);" 1000)
|
|
|
|
|
|
|
|
; will throw a Error exception
|
|
|
|
|
2013-02-08 11:50:25 -05:00
|
|
|
call function with timeout::
|
|
|
|
|
|
|
|
user=> (def f (js/compile-function scope "function () { while(true); }"))
|
|
|
|
#'user/f
|
|
|
|
user=> (js/call-timeout scope f 1000)
|
|
|
|
TimeOutError
|
|
|
|
org.marianoguerra.rhino.TimedContextFactory.observeInstructionCount
|
|
|
|
(TimedContextFactory.java:47)
|
|
|
|
|
|
|
|
; function that doesn't timeout
|
|
|
|
user=> (def f1 (js/compile-function scope "function (a, b) { return a +
|
|
|
|
b; }"))
|
|
|
|
#'user/f1
|
|
|
|
user=> (js/call-timeout scope f1 1000 1 3)
|
|
|
|
4.0
|
|
|
|
|
2013-01-08 10:55:55 -05:00
|
|
|
license?
|
|
|
|
--------
|
|
|
|
|
|
|
|
it seems the clojure people under this circumstances say something like:
|
|
|
|
|
|
|
|
Copyright © 2013 marianoguerra
|
|
|
|
|
|
|
|
Distributed under the Eclipse Public License, the same as Clojure.
|