On Wed, Dec 24, 2014 at 9:30 PM, Howard Lewis Ship <hls...@gmail.com> wrote:

> I don't see why you need to make the var dynamic, as it contains a mutable
> value (a promise) itself.
>

Actually it's not needed. Counterclockwise plugin complained about
non-dynamic global var, so I made it dynamic to avoid this warning.


> 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.
>

Great idea! That would make a lot of sense to have instant access to
Tapestry services from Clojure runtime.


> 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
>



-- 
Ilya Obshadko

Reply via email to