defmacro, an optional parameter, and a block

83 views
Skip to first unread message

...Paul

unread,
Jul 20, 2016, 4:32:37 PM7/20/16
to elixir-lang-talk
I'm going nucking futs trying to work out how to make this work, so I'm finally going to reach out here.  I'm betting it's something really simple I'm just not getting.

I've got a macro working that is used like this:

properties do
  ...
end

The macro definition looks like:

defmacro properties(do: block) do...

But now I'd like to be able to put an optional keyword parameter in there:

properties id: :string, do  # Alternatively, properties [id: :string], do
  ...
end

I can't seem to work out how to make that happen.  I've tried a bunch of things

defmacro properties(options \\ [], [do: block]) do
defmacro properties(options) do  # Expecting [id: string, do: block]

I've tried combining the above with "properties(id: :string) do" with "properties [id: :string], do" and "properties [id: :string] do" and just can't seem to hit on the correct syntax.

I expect this has to be possible, what combination have I missed that will make it work? :)

...Paul



José Valim

unread,
Jul 20, 2016, 4:35:45 PM7/20/16
to elixir-l...@googlegroups.com
One straight-forward approach is to write:

defmacro properties(opts \\ [], block []) do
  opts = Keyword.merge(opts, block)
  ... business as usual ...
end

Does this work?

José Valim
Skype: jv.ptec
Founder and Director of R&D

--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/d90548c5-bb02-4417-877e-1c344bc462df%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

...Paul

unread,
Jul 20, 2016, 4:43:30 PM7/20/16
to elixir-lang-talk, jose....@plataformatec.com.br
Aha, of course, I forgot to default the second parameter.  I think I was thinking the do: block keyword list would "always be last" (coming from Ruby, where it is...)

For reference, you forgot the \\ between "block" and "[]" -- but once I figured that out, this worked.  THANKS!

...Paul

...Paul

unread,
Jul 20, 2016, 4:59:15 PM7/20/16
to elixir-lang-talk, jose....@plataformatec.com.br
Argh, turns out I forgot a "do" in the defmodule before the macro was used, totally threw me off.  Turns out, this worked fine:

defmacro properties(options \\ [id: :string], [do: block]) do

*facepalm*

...Paul


Reply all
Reply to author
Forward
0 new messages