On Mon, Jan 23, 2012 at 3:54 AM, Tassilo Horn <tass...@member.fsf.org> wrote:
> Michael Klishin <michael.s.klis...@gmail.com> writes:
>
> Hi Michael,
>
>> I am trying to make it possible to use functions as Quartz jobs for my
>> Clojure DSL on top of Quartz [1]. For that, I need to implement a
>> simple 1-method interface. Both gen-class and defrecord with
>> additional methods work great but seem too heavyweight in many cases
>> so I am trying to add function support using core/proxy.
>>
>> The interface I need to implement looks like this:
>>
>> https://gist.github.com/63989c1a081737813f99
>>
>> and my code is basically this:
>>
>> https://gist.github.com/a83687aed4ea62c915f5
>>
>> However, when Quartz tries to execute a new job instance,
>> UnsupportedOperationException is raised as if execute was not
>> implemented.
>
> I don't know Quartz, but checking your gist, it seems that you don't
> actually do anything with the proxy object except getting its class and
> "registering" it with some JobBuilder.
>
> Although the class generated by proxy can be instantiated using a
> zero-args constructor, those new instances don't behave like the object
> returned by proxy itself.
>
> Here's an example without additional deps illustrating the issue.
>
> --8<---------------cut here---------------start------------->8---
> (defn using-fn [f]
>  (let [prx (proxy [java.util.concurrent.Delayed] []
>              (getDelay [tu]
>                (f 0)))
>        clazz (class prx)]
>    [prx clazz]))  ;; return the proxy object and its class
>
> ;; Calling getDelay on the proxy object works
> (.getDelay (first (using-fn inc)) java.util.concurrent.TimeUnit/SECONDS)
> ;=> 1
>
> ;; Creating a new instance of the class generated by proxy also works
> (.newInstance (second (using-fn inc)))
> ;=> #<Object$Delayed$333735ab 
> user.proxy$java.lang.Object$Delayed$333735ab@7746e075>
>
> ;; However, that new instance doesn't work as expected
> (.getDelay (.newInstance (second (using-fn inc))) 
> java.util.concurrent.TimeUnit/SECONDS)
> ; getDelay
> ;   [Thrown class java.lang.UnsupportedOperationException]
> ; Evaluation aborted.
> --8<---------------cut here---------------end--------------->8---
>
> Generally, proxy is for creating proxy objects, and the generation of a
> class is more or less a side effect.
>
> Do I see it correctly that you need a way (1) to have objects
> implementing Job which (2) can be instantiated with a zero-args
> constructor and (3) whose execute behavior is customizable by providing
> an arbitrary function f on the JobExecutionContext?
>
> If so, I don't see a too good way.  deftype would be usable if the
> function f would be specified as a field of the type, but then it has no
> zero-args constructor...

(let [f (atom (fn [_] (throw (IllegalStateException.))))]
  (defn set-job-fn! [x]
    (reset! f x))
  (deftype Job []
    Job
    (execute [ctx]
      (@f ctx))))

Elaborate as you see fit with e.g. a with-job-fn macro or whatever
inside the let.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to