httpoison icon indicating copy to clipboard operation
httpoison copied to clipboard

refine overridable functions when using module Base.

Open nanne007 opened this issue 10 years ago • 3 comments

The defoverridable Module.definitions_in(__MODULE__) can cause some unexpected behaviors. Such as, when defining struct in the module using HTTPoison.Base, the __struct__ function will be lazily defined, which causes %__MODULE__{} cannot function correctly.

defmodule FooBar do
  defmacro __using__(_) do
    quote do
      defoverridable Module.definitions_in(__MODULE__)
      Module.definitions_in(__MODULE__) |> IO.inspect
    end
  end
end

defmodule MyModule do
  defstruct bar: nil
  use FooBar
  def foo(%__MODULE__{bar: bar}), do: bar
end

# ====>
# ** (CompileError) test.ex:17: MyModule.__struct__/0 is undefined, cannot expand struct MyModule
#    (elixir) src/elixir_map.erl:58: :elixir_map.translate_struct/4
#    (stdlib) lists.erl:1353: :lists.mapfoldl/3

nanne007 avatar Jan 06 '16 10:01 nanne007

I just found out that one can use FooBar first to prevent the situation.

defmodule FooBar do
  defmacro __using__(_) do
    quote do
      defoverridable Module.definitions_in(__MODULE__)
      Module.definitions_in(__MODULE__) |> IO.inspect
    end
  end
end

defmodule MyModule do
  use FooBar
  defstruct bar: nil
  def foo(%__MODULE__{bar: bar}), do: bar
end

So I just close the PR.

nanne007 avatar Jan 07 '16 13:01 nanne007

I think this is an actual bug and it should not be order dependent. Do you mind reopening the PR (if still available)?

edgurgel avatar Jan 08 '16 00:01 edgurgel

@edgurgel Here it is.

nanne007 avatar Jan 08 '16 01:01 nanne007