vrod

vrod

Adding more to __using__?

Is there a way to put more functions into __using__ block? It gets very long and hard to read. I cannot figure out how to split up the quote do into multiple functions. Is there a trick?

Most Liked

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Yea I agree with @eksperimental here, this use of macros generally causes more trouble than it’s worth.

If you find yourself with functions that take too many arguments, consider creating a struct and then passing on that struct. For example:

defmodule SomeModule do
  defstruct [shared1: "a", shared2: "b", foo: nil, bar: nil]
end

Then you construct a %SomeModule{} struct and it will take on the relevant defaults, and also provide a place to store other values you want to set. Then you can pass this to your various functions, and add extra arguments as appropriate.

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

@vrod I’ll start by saying: If this is a problem you’re running into, you are 100% putting too much inside of a __using__ block. Code inside of a using block should generally look like this:

defmodule SomeThing do
  defmacro __using__(opts) do
    quote do
      def foo(arg) do
        SomeThing.foo(__MODULE__, arg)
      end
    end
  end

  def foo(module, arg) do
    # complex multi-line implementation here
  end
end

NOT

defmodule SomeThing do
  defmacro __using__(opts) do
    quote do
      def foo(arg) do
        # complex multi-line implementation here
      end
    end
  end
end

Doing it the first way will improve compile times, debugging ability, and avoid the problem you are running into.

BUT, to actually answer your question, you can do this;

defmacro __using__(opts) do
  [
    first_part_stuff(opts),
    second_part_stuff(opts),
  ]
end

defp first_part_stuff(opts) do
  quote do
    # things here
  end
end

defp second_part_stuff(opts) do
  quote do
    # things here
  end
end

Basically, return a list of quote do blocks.

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

You can @doc false those functions if you want to make it clear that they aren’t supposed to be used.

Where Next?

Popular in Questions Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

Other popular topics Top

JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

We're in Beta

About us Mission Statement