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

Reply via email to