Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eprothro/6343139dccd7cf8c67e766ada0b1c598 to your computer and use it in GitHub Desktop.
Save eprothro/6343139dccd7cf8c67e766ada0b1c598 to your computer and use it in GitHub Desktop.
defmodule VanillaTest do
  
  def foo(%{arg: arg}) do
    IO.inspect("foo/1 with map called: #{arg}")
    foo("success")
  end
  
  def foo(arg) do
    IO.inspect("implementation function foo/1 called: #{arg}")
    case arg do
      "success" -> :ok
      _ -> :error
    end
  end
end

VanillaTest.foo(%{arg: "failure"})

#=> "foo/1 with map called: failure"
#=> "implementation function foo/1 called: success"
#=> :ok

defmodule FoofulFromUsing do
  defmacro __using__(_) do
    quote do
      def foo(arg) do
        IO.inspect("implementation function FoofulFromUsing.foo/1 called: #{inspect(arg)}")
        case arg do
          "success" -> :ok
          _ -> :error
        end
      end
    end
  end
end

defmodule UsingTest do
  use FoofulFromUsing
  
  def foo(%{arg: arg}) do
    IO.inspect("foo/1 with map called: #{arg}")
    foo("success")
  end
end
UsingTest.foo(%{arg: "failure"})

#=> "implementation function FoofulFromUsing.foo/1 called: %{arg: \"failure\"}"
#=> :error


# using use after function definition adds to the AST after #
# the calling Module definitions are added from using. But awkward.
defmodule UsingAfterTest do
  def foo(%{arg: arg}) do
    IO.inspect("foo/1 with map called: #{arg}")
    foo("success")
  end
  
  use FoofulFromUsing
end

UsingAfterTest.foo(%{arg: "failure!"})

#=> "foo/1 with map called: failure!"
#=> "implementation function FoofulFromUsing.foo/1 called: \"success\""
#=> :ok

# using before_compile adds to the AST after #
# the calling Module definitions
defmodule FoofulFromBeforeCompile do
  defmacro __using__(_) do
    quote do
      @before_compile FoofulFromBeforeCompile
    end
  end
    
  defmacro __before_compile__(_env) do
    quote do
      def foo(arg) do
        IO.inspect("implementation function FoofulFromUsing.foo/1 called: #{arg}")
        case arg do
          "success" -> :ok
          _ -> :error
        end
      end
    end
  end
end

defmodule BeforeCompileTest do
  use FoofulFromBeforeCompile
  
  def foo(%{arg: arg}) do
    IO.inspect("foo/1 with map called: #{arg}")
    foo("success")
  end
end

BeforeCompileTest.foo(%{arg: "failure"})

#=> "foo/1 with map called: failure"
#=> "implementation function FoofulFromUsing.foo/1 called: success"
#=> :ok
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment