Unable to resolve symbol: execute-method-chain in this context

23 views
Skip to first unread message

bili

unread,
Mar 22, 2019, 6:31:24 AM3/22/19
to Ring
hey guys, I wrote these code, want to do some cool thing, but I got an error, I don't know where am I wrong, please give me some help, thanks!

(ns ring-demo.core
(:require [ring.adapter.jetty :as jetty]
))

(defn method-1 [request]
{:status 200
:headers {"Content-Type" "text/plain"}
:body (str "Hello World" (:is-bili request))})

(defn method-2 [request]
(assoc request :is-bili true))

(defn get-method-chain [request]
'(method-2 method-1))

(defn execute-method-chain [request method-chain]
(concat `(-> ~request) method-chain))

(defn handler [request]
(let [path (:uri request)]
(print path)
(cond (= path "/")
(eval '(execute-method-chain request (get-method-chain request)))
:else
())))

(def app
"app domain"
handler)

I run the code with lein ring server

my project.cli like this

(defproject ring-demo "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.10.0"]
[ring/ring-core "1.6.3"]
[ring/ring-jetty-adapter "1.6.3"]
[ring-logger "1.0.1"]
[ring/ring-devel "1.6.3"]]
:repl-options {:init-ns ring-demo.core}
:ring {:handler ring-demo.core/app}
:plugins [[org.clojure/core.unify "0.5.7"]
[lein-ring "0.12.4" :exclusions [org.clojure/core.unify]]])

James Reeves

unread,
Mar 22, 2019, 6:36:52 AM3/22/19
to Ring
I'm not sure why you're using eval and storing symbols, instead of just having the functions in an list.

You appear to have an errant ' in front of your eval argument. Perhaps that's your issue?


--
You received this message because you are subscribed to the Google Groups "Ring" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ring-clojure...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
James Reeves

X X

unread,
Mar 22, 2019, 7:02:57 AM3/22/19
to ring-c...@googlegroups.com
thank you reply to me, I want to build a module system, each method can be swap and  constitute, I fixed my code:
(defn handler [request]
(let [path (:uri request)]
(print path)
(cond (= path "/")
(eval (execute-method-chain request (get-method-chain request)))
:else
())))
and I load the file and run a followed code in REPL, it work fine
(eval (execute-method-chain {} (get-method-chain {})))
=> {:status 200, :headers {"Content-Type" "text/plain"}, :body "Hello Worldtrue"}
but when I run it with  lein ring server
I got a new error

clojure.lang.Compiler$CompilerException

Syntax error compiling fn* at (0:0).
Compiler.java:7114clojure.lang.Compiler.analyzeSeq
Compiler.java:6789clojure.lang.Compiler.analyze
Compiler.java:7173clojure.lang.Compiler.eval
Compiler.java:7131clojure.lang.Compiler.eval
core.clj:3214clojure.core/eval
core.clj:3210clojure.core/eval
core.clj:29ring-demo.core/handler
core.clj:25ring-demo.core/handler
Var.java:384clojure.lang.Var.invoke
reload.clj:39ring.middleware.reload/wrap-reload[fn]
stacktrace.clj:26ring.middleware.stacktrace/wrap-stacktrace-log[fn]
stacktrace.clj:96ring.middleware.stacktrace/wrap-stacktrace-web[fn]
jetty.clj:25ring.adapter.jetty/proxy-handler[fn]
(Unknown Source)ring.adapter.jetty.proxy$org.eclipse.jetty.server.handler.AbstractHandler$ff19274a.handle
HandlerWrapper.java:97org.eclipse.jetty.server.handler.HandlerWrapper.handle
Server.java:499org.eclipse.jetty.server.Server.handle
HttpChannel.java:311org.eclipse.jetty.server.HttpChannel.handle
HttpConnection.java:258org.eclipse.jetty.server.HttpConnection.onFillable
AbstractConnection.java:544org.eclipse.jetty.io.AbstractConnection$2.run
QueuedThreadPool.java:635org.eclipse.jetty.util.thread.QueuedThreadPool.runJob
QueuedThreadPool.java:555org.eclipse.jetty.util.thread.QueuedThreadPool$3.run
Thread.java:834java.lang.Thread.run

Caused by java.lang.RuntimeException

Can't embed object in code, maybe print-dup not defined: HttpInputOverHTTP@609e9ea
Util.java:221clojure.lang.Util.runtimeException
Compiler.java:4893clojure.lang.Compiler$ObjExpr.emitValue
Compiler.java:4704clojure.lang.Compiler$ObjExpr.emitListAsObjectArray
Compiler.java:4835clojure.lang.Compiler$ObjExpr.emitValue
Compiler.java:4934clojure.lang.Compiler$ObjExpr.emitConstants
Compiler.java:4612clojure.lang.Compiler$ObjExpr.compile
Compiler.java:4106clojure.lang.Compiler$FnExpr.parse
Compiler.java:7104clojure.lang.Compiler.analyzeSeq
Compiler.java:6789clojure.lang.Compiler.analyze
Compiler.java:7173clojure.lang.Compiler.eval
Compiler.java:7131clojure.lang.Compiler.eval
core.clj:3214clojure.core/eval
core.clj:3210clojure.core/eval
core.clj:29ring-demo.core/handler
core.clj:25ring-demo.core/handler
Var.java:384clojure.lang.Var.invoke
reload.clj:39ring.middleware.reload/wrap-reload[fn]
stacktrace.clj:26ring.middleware.stacktrace/wrap-stacktrace-log[fn]
stacktrace.clj:96ring.middleware.stacktrace/wrap-stacktrace-web[fn]
jetty.clj:25ring.adapter.jetty/proxy-handler[fn]
(Unknown Source)ring.adapter.jetty.proxy$org.eclipse.jetty.server.handler.AbstractHandler$ff19274a.handle
HandlerWrapper.java:97org.eclipse.jetty.server.handler.HandlerWrapper.handle
Server.java:499org.eclipse.jetty.server.Server.handle
HttpChannel.java:311org.eclipse.jetty.server.HttpChannel.handle
HttpConnection.java:258org.eclipse.jetty.server.HttpConnection.onFillable
AbstractConnection.java:544org.eclipse.jetty.io.AbstractConnection$2.run
QueuedThreadPool.java:635org.eclipse.jetty.util.thread.QueuedThreadPool.runJob
QueuedThreadPool.java:555org.eclipse.jetty.util.thread.QueuedThreadPool$3.run
Thread.java:834java.lang.Thread.run

James Reeves <ja...@booleanknot.com> 于2019年3月22日周五 下午6:36写道:

James Reeves

unread,
Mar 22, 2019, 7:56:14 AM3/22/19
to Ring
You don't need eval for that. It's generally better to work with a collection of functions, rather than symbols. For example:

  (defn get-method-chain [request]
    [method-2 method-1])

  (defn execute-method-chain [request method-chain]
    ((apply comp (reverse method-chain)) request))

If you want to use eval for whatever reason, you need to ensure that you're not trying to serialize the request. So you'd write:

  (eval (execute-method-chain 'request (get-method-chain request)))

So in the above code we're passing the request symbol, which can be serialized, instead of the full request, which can't be because it has an input stream in it.

I'd advise against using eval in this case. I'd also suggest looking up how middleware and interceptors work. Interceptors especially look like what you're trying to achieve with your method chain.

X X

unread,
Mar 22, 2019, 8:10:44 AM3/22/19
to ring-c...@googlegroups.com
Thank you, it works for me! It's my first time to communicate with a community, it is cool!

James Reeves <ja...@booleanknot.com> 于2019年3月22日周五 下午7:56写道:
Reply all
Reply to author
Forward
0 new messages