deftemplate and dynamic vars

88 views
Skip to first unread message

Anthony Grimes

unread,
Feb 13, 2012, 3:48:56 PM2/13/12
to enliv...@googlegroups.com
I created https://github.com/cgrand/enlive/issues/30 last night.

The issue seems to be that when you call a template function, it is not executed within the dynamic scope of the caller. Here is my specific code: https://refheap.com/paste/4f39738de4b07508daafd022

In my code, I always call 'layout' inside of a Noir defpage which sets session/*noir-session* to a session map. However, whenever I call this code, *noir-session* remains unbound. I've also tested by trying to bind something innocent like *out* and it doesn't get communicated to the template either. It's as if deftemplate creates its function with bound-fn (which doesn't seem to be the case).

I talked to Chas Emerick on IRC and he encouraged me to ping the ML about it. He seems to have confirmed the bug himself.

Christophe Grand

unread,
Feb 14, 2012, 11:53:07 AM2/14/12
to enliv...@googlegroups.com
Hi,

Templates return a lazy-seq, so it's the opposite behaviour of being created by bound-fn that you observe.

The most expedient way to solve this problem is to have a middleware which calls doall (or map (bound-fn [x] x) if you want to preserve laziness) on the :body of the response map -- thus the lazy seq evaluation will happen inside the dynamic scope set by upstream middlewares.

Given that per Ring's spec, :body may be lazy seqs, I would tend to say that it's up to the authors of middlewares which introduce dynamic binding to ensure that this case is covered.

I don't want to fix this systematically at the heart of Enlive because bound-fn incurs a overhead.
However in a first time, I'm ok with shipping a body-forcing middleware before finding a better solution. Would it be ok with you?

hth,

Christophe

--
You received this message because you are subscribed to the Google Groups "Enlive" group.
To view this discussion on the web visit https://groups.google.com/d/msg/enlive-clj/-/xE2r3csD9SwJ.
To post to this group, send email to enliv...@googlegroups.com.
To unsubscribe from this group, send email to enlive-clj+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/enlive-clj?hl=en.



--
Professional: http://cgrand.net/ (fr)
On Clojure: http://clj-me.cgrand.net/ (en)

Christophe Grand

unread,
Feb 19, 2012, 6:37:02 AM2/19/12
to enliv...@googlegroups.com
While on the road I realized that the laziness at the origin of the problem is uncorelated with the desired laziness.
https://github.com/cgrand/enlive/commit/698343e456287c5f744bf6170426d33ccd6d6e3a

Thanks for the report.

(I still think in the general case, middleware writers should take care of lazy bodies.)

Christophe
Reply all
Reply to author
Forward
0 new messages