Nope, never mind - it was a dirty REPL. It works fine-ish.
My next problem is that it works fine, but only if I call it in the
namespace it is defined in. If I call it in another namespace I get the
following error:
Error refreshing environment: java.lang.RuntimeException: Can't refer to
qualified var that doesn't exist,
compiling:(my/domain/internal/service/location.clj:43:3)
If I put the macro-expanded code inline in the other namespace:
(do
(schema.core/defn
qfi.health.domain.internal.support.crud-handler/create
:-
[qfi.health.domain.events/LocationDefinedSchema]
[detail__3316__auto__
:-
(:detail qfi.health.domain.commands/DefineLocationSchema)]
(clojure.core/let
[ar__3317__auto__
(qfi.health.domain.internal.model.common/new-ar
detail__3316__auto__)
event__3318__auto__
(qfi.health.domain.events/event
:location-defined
ar__3317__auto__)]
[event__3318__auto__])))
then the error is on the (schema.core/defn) call. But notice the fully
qualified 'create' - I want 'create' to be a literal in the namespace of
the caller, not the namespace the macro is defined in.
Any ideas?
On Friday, 13 March 2015 12:27:02 UTC, Colin Yates wrote:
>
> Hi,
>
> I am wiring up a bunch of CRUD command handlers for different aggregates
> using prismatic schema to validate and it is screaming out for a macro, but
> my ignorance is screaming even louder :).
>
> The form I want to emit is something like (for a 'Location' for example):
>
> (s/defn ^:always-validate create :- [events/LocationDefinedSchema]
> [detail :- (-> commands/DefineLocationSchema :detail)]
> (let [ar (common/new-ar detail)
> event (events/event :location-defined ar)]
> [event]))
>
>
> Where 'events/LocationDefinedSchema' and 'commands/DefineLocationSchema'
> are prismatic schemas.
>
> To make it generic (and relying on convention) then once I have the
> aggregate I can do:
>
> (def aggregate :location)
>
> (def DefineCommandSchema (symbol (str "my.domain.commands/Define"
> (clojure.string/capitalize (name aggregate)) "Schema")))
>
> (def DefinedEventSchema (symbol (str "my.domain.events/"
> (clojure.string/capitalize (name aggregate)) "DefinedSchema")))
> (def defined-event-key (keyword (str (name aggregate) "-defined")))
> (def define-command-key (keyword (str "define-" (name aggregate))))
>
>
> which allows the generic create form to be:
>
> (s/defn ^:always-validate create :- [DefinedEventSchema]
> [detail :- (-> DefineCommandSchema :detail)]
> (let [ar (common/new-ar detail)
> event (events/event defined-event-key ar)]
> [event]))
>
>
> I then tried to extract this into a macro:
>
> (defmacro create-infrastructure
>
> [aggregate]
> (let [{:keys [define-command-schema
> defined-event-schema
> define-command-key
> defined-event-key]} (default-options aggregate)]
>
> `(do
> (schema.core/defn ^:always-validate create :-
> [~defined-event-schema]
> [detail# :- (:detail ~define-command-schema)]
> (let [ar# (common/new-ar detail#)
> event# (events/event ~defined-event-key ar#)]
> [event#])))
>
> ))
>
>
> Where 'default-options' just returns a map with the specified keys and
> constructs some symbols.
>
> Unfortunately the emitted form is:
>
> (macroexpand-1 '(create-infrastructure :location))
> => (do
> (schema.core/defn my.domain.internal.support.crud-handler/create :-
> [my.domain.events/LocationDefinedSchema] [detail__10635__auto__ :-
> (:detail my domain.commands/DefineLocationSchema)] (clojure.core/let
> [ar__10636__auto__ (my.domain.internal.model.common/new-ar
> detail__10635__auto__) event__10637__auto__ (my.domain.events/event
> :location-defined ar__10636__auto__)] [event__10637__auto__])))
>
> This works somewhat but it is missing the '^:always-validate' and I have
> tried to use (with-meta) but it just doesn't to do what I want.
>
> Any suggestions on getting the meta to pass through or thoughts on this
> macro in general are greatly appreciated!
>
> Thanks!
>
> ----
>
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.