Sto cercando un modo per chiamare una funzione dato il suo nome di stringa in clojureScript.chiama una funzione clojurescript per nome stringa
Qualcosa di simile:
(call "my-fun" args)
Qualsiasi aiuto di benvenuto
Sto cercando un modo per chiamare una funzione dato il suo nome di stringa in clojureScript.chiama una funzione clojurescript per nome stringa
Qualcosa di simile:
(call "my-fun" args)
Qualsiasi aiuto di benvenuto
Questo non è possibile, come una volta si utilizza la modalità di compilazione avanzata di ClojureScript poi tutti i nomi delle funzioni sono "munged", quindi non ci sarebbe modo di mappare una stringa a una funzione mungita quando si desidera chiamarla
Avevo bisogno di un modo di chiamare una funzione il cui ns/nome è caricato dinamicamente. Come notato, non esiste un modo supportato per farlo. Tuttavia, questo è ciò che gli hack sono per. Ecco quello che ho finito per fare:
cljs Calling:
(js/proxy "my-ns/my-fun" args)
Proxy.js:
function proxy() {
var args = Array.prototype.slice.call(arguments);
var nsFunc = args[0].replace(/-/g, "_").replace(/\//g, ".");
eval(nsFunc).apply(null, args.slice(1));
}
cljs dinamicamente risolti:
(ns my-ns)
(defn ^:export my-fun [args] ...)
I metadati esportazione dice al compilatore di chiusura non munge il nome, quindi funziona anche con la compilazione in modalità avanzata. Inutile dire che questo non è un codice solido come il rock che è garantito per funzionare in futuro, ma tu hai l'idea.
Una soluzione abbastanza hacker che dovrebbe funzionare:
(ns eval.core
(:require [clojure.string :as str]))
(defn ->js [var-name]
(-> var-name
(str/replace #"/" ".")
(str/replace #"-" "_")))
(defn invoke [function-name & args]
(let [fun (js/eval (->js function-name))]
(apply fun args)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Usage:
(ns example.core
(:require [eval.core :as e]))
(defn ^:export my-fn [arg1 arg2] ;; Note the export!
(println arg1 arg2)
arg2)
(e/invoke "example.core/my-fn" 5 6) ;=> 5 6
Finché non si utilizza l'ottimizzazione avanzata per il compilatore:
(def global (this-as this this))
(defn call [fname & args]
(.apply (aget global fname) global args))
(call "String" 123)
global
è legato al global object per qualsiasi piattaforma da utilizzando l'operatore this
nell'ambito globale. È possibile utilizzare .call
invece di .apply
come in:
(.call (aget global "String") global 123)
La stessa tecnica può essere utilizzata anche con altri oggetti rispetto al globale.
http://stackoverflow.com/a/12020663/62082 può fornire qualche aiuto –