I don't see why you need to make the var dynamic, as it contains a mutable value (a promise) itself.
However, this does bring to mind an idea for 5.5, that Tapestry could define a dynamic Var to contain the registry, and bind that Var whenever it invokes a Clojure function via the interop. On Mon, Dec 22, 2014 at 10:51 AM, Ilya Obshadko <ilya.obsha...@gmail.com> wrote: > No, I didn't try getObject() yet. That means the code for injection would > be a little bit more complex, but I'll explain using "simple" version from > the previous message: > > https://gist.github.com/xfyre/f6a62b3f63ed01929054 > > Line 4: define dynamic global variable as (promise) - it's not available at > the time of compilation. > > Lines 6-8: this is a Tapestry-mapped function that will be called during > @Startup phase to "deliver" ObjectLocator instance (after promise was > delivered, it becomes immutable and can't be mutated anymore). > > Lines 10-15: macro that accepts service-bindings in a usual Clojure > bindings format, like [hibernate-session Session my-service MyService], > when odd entries are variable names and even entries are class names (in > Clojure you don't need to use .class). The macro reconstructs this list so > Class names are > converted to getService() calls, and then during let binding (syntax > unquote on line 15) those services are finally bound to variables for the > later use. > > Lines 19-23 is an example of using this macro. > > > On Sun, Dec 21, 2014 at 10:22 PM, Thiago H de Paula Figueiredo < > thiag...@gmail.com> wrote: > > > On Thu, 18 Dec 2014 20:01:11 -0200, Ilya Obshadko < > ilya.obsha...@gmail.com> > > wrote: > > > > One more question regarding ObjectLocator. > >> Turns out it cannot resolve services like Logger, complaining that no > >> service implements its interface. > >> Could you suggest how to solve it? > >> > > > > Have you tried getObject() instead of getService()? Logger isn't a > > Tapestry-IoC service (unless you create it, of course), so you cannot use > > getService() to get it. > > > > By the way, as someone who wants to learn Clojure, could you please > > explain your Clojure snippet? :) > > > > > > > >> On Thu, Dec 18, 2014 at 11:20 PM, Ilya Obshadko < > ilya.obsha...@gmail.com> > >> wrote: > >> > >> So, my solution for this is actually quite simple: > >>> > >>> (ns com.xdance.tapestry.serviceregistry > >>> > >>> (:import (org.apache.tapestry5.ioc ObjectLocator))) > >>> > >>> > >>> (def ^:dynamic ^ObjectLocator *tapestry-registry-ref* (promise)) > >>> > >>> > >>> (defn init-registry [^ObjectLocator registry] > >>> > >>> "Must be called during service initialization to set up Tapestry > >>> registry object" > >>> > >>> (deliver *tapestry-registry-ref* registry)) > >>> > >>> > >>> (defmacro with-tapestry-services [service-bindings & body] > >>> > >>> "Apply service bindings to body" > >>> > >>> (let [service-binding-pairs (partition-all 2 service-bindings) > >>> > >>> service-binding-exprs (map #(vector (first %1) `(.getService ( > >>> deref *tapestry-registry*) ~(second %1))) service-binding-pairs) > >>> > >>> service-binding-final (vec (reduce concat > >>> service-binding-exprs))] > >>> > >>> `(let ~service-binding-final ~@body))) > >>> > >>> > >>> The only thing I need to do is to bind init-registry function to > Tapestry > >>> service interface and call it during startup phase. There might be > better > >>> approaches probably. > >>> > >>> On Thu, Dec 18, 2014 at 6:49 PM, Ilya Obshadko < > ilya.obsha...@gmail.com> > >>> wrote: > >>> > >>> Thanks Howard, that's making a lot of sense. > >>>> > >>>> However my initial though was about injecting Clojure globals > >>>> (specifically, one global containing service registry) during the call > >>>> to > >>>> "require" IFn. I still couldn't find any ways to manipulate initial > >>>> Clojure > >>>> environment, although there are obvious workarounds (for example I > could > >>>> have a specific function inside Clojure namespace that could be used > to > >>>> inject necessary objects using mutable globals). I'm still looking for > >>>> more > >>>> concise and accurate way to do that. > >>>> > >>>> On Thu, Dec 18, 2014 at 7:35 AM, Howard Lewis Ship <hls...@gmail.com> > >>>> wrote: > >>>> > >>>> Actually, Clojure interop with Java is very good, so a Clojure > function > >>>>> could be passed a Java object: > >>>>> > >>>>> (defn frobnicate-the-request > >>>>> [^Request request] > >>>>> (.setAttribute request "xyzzyx" (compute-the-magic-name))) > >>>>> > >>>>> The ^Request part is a type hint, it allows the Clojure compiler to > >>>>> generate proper bytecode to access the methods of the request without > >>>>> using > >>>>> reflection. > >>>>> > >>>>> You quickly get used to the leading dot (which itself is sugar syntax > >>>>> over > >>>>> the more primitive interop special form). > >>>>> > >>>>> Now, in terms of Clojure interop ... the library I put together ago > on > >>>>> a > >>>>> whim was about efficiently exposing Clojure functions bundled > together > >>>>> as > >>>>> an arbitrary Java interface. > >>>>> > >>>>> If you pass the Registry to a Clojure function, it will be quite > >>>>> capable > >>>>> of > >>>>> pulling out whatever it needs. > >>>>> > >>>>> A lot of the capabilities of Clojure are very familiar to Tapestry > >>>>> users: > >>>>> thread bound values (inside Clojure vars) for example. > >>>>> > >>>>> My primary thought about integrating Clojure would be to allow a > >>>>> Tapestry > >>>>> app to jump into Clojure to work with the Datomic APIs natively, > rather > >>>>> than the Java API to Datomic, which is decidedly second class. > >>>>> > >>>>> On Tue, Dec 16, 2014 at 5:24 AM, Thiago H de Paula Figueiredo < > >>>>> thiag...@gmail.com> wrote: > >>>>> > > >>>>> > On Mon, 15 Dec 2014 18:29:22 -0200, Ilya Obshadko < > >>>>> ilya.obsha...@gmail.com> > >>>>> > wrote: > >>>>> > > >>>>> > > >>>>> > How are Java objects usually passed to Clojure code? The > recommended > >>>>> way? > >>>>> >>> > >>>>> >> > >>>>> >> Java objects are passed to Clojure functions in exactly the same > way > >>>>> they > >>>>> >> are passed to Java method (because internally Clojure function is > >>>>> just an > >>>>> >> implementation of IFn interface, and function call is invoke(...) > on > >>>>> its > >>>>> >> instance). > >>>>> >> > >>>>> > > >>>>> > Now I was the one who hasn't made a clear question. :) I'm not > asking > >>>>> > about how Clojure passes function arguments. I meant when you call > >>>>> Clojure > >>>>> > code from Java code, how do you pass a Java object so it can be > used > >>>>> inside > >>>>> > Clojure code? > >>>>> > > >>>>> > But I don't want to pass services to Clojure functions, I'd like > to > >>>>> >> inject them into Clojure namespace when clojure.core/require is > >>>>> executed. > >>>>> >> > >>>>> > > >>>>> > Got it. I have no idea how to do that given my almost no knowledge > of > >>>>> > Clojure. But I guess there's some way of doing that. > >>>>> > > >>>>> > > >>>>> > -- > >>>>> > Thiago H. de Paula Figueiredo > >>>>> > Tapestry, Java and Hibernate consultant and developer > >>>>> > http://machina.com.br > >>>>> > > >>>>> > ------------------------------------------------------------ > >>>>> --------- > >>>>> > To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org > >>>>> > For additional commands, e-mail: users-h...@tapestry.apache.org > >>>>> > > >>>>> > > >>>>> > >>>>> -- > >>>>> Howard M. Lewis Ship > >>>>> > >>>>> Creator of Apache Tapestry > >>>>> > >>>>> The source for Tapestry training, mentoring and support. Contact me > to > >>>>> learn how I can get you up and productive in Tapestry fast! > >>>>> > >>>>> (971) 678-5210 > >>>>> http://howardlewisship.com > >>>>> @hlship > >>>>> > >>>>> > >>>> > >>>> > >>>> -- > >>>> Ilya Obshadko > >>>> > >>>> > >>>> > >>> > >>> -- > >>> Ilya Obshadko > >>> > >>> > >>> > >> > >> > > > > -- > > Thiago H. de Paula Figueiredo > > Tapestry, Java and Hibernate consultant and developer > > http://machina.com.br > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org > > For additional commands, e-mail: users-h...@tapestry.apache.org > > > > > > > -- > Ilya Obshadko > -- Howard M. Lewis Ship Creator of Apache Tapestry The source for Tapestry training, mentoring and support. Contact me to learn how I can get you up and productive in Tapestry fast! (971) 678-5210 http://howardlewisship.com @hlship