Skip to content

Instantly share code, notes, and snippets.

@pikender
Last active April 13, 2016 07:57
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save pikender/892fd3707043bacecc73ad24ba45cdba to your computer and use it in GitHub Desktop.
Model Support Function Extension
## Library Code
## Defines DSL to be used by Service Code
## in order to get properly consumed by Consumer
defmodule Nectar.ModelExtension do
defmacro __using__(_opts) do
quote do
Module.register_attribute(__MODULE__, :method_block, accumulate: true)
import Nectar.ModelExtension, only: [include_method: 1]
@before_compile Nectar.ModelExtension
defmacro __using__(_opts) do
quote do
# can be generlaised by unquote(__MODULE__)
import Nectar.ExtendProduct, only: [include_methods: 0]
@before_compile Nectar.ExtendProduct
end
end
end
end
# Part of Method Addition DSL
defmacro include_method([do: block]) do
support_fn = Macro.escape(block)
quote bind_quoted: [support_fn: support_fn] do
Module.put_attribute(__MODULE__, :method_block, support_fn)
end
end
defmacro __before_compile__(_env) do
quote do
defmacro include_methods do
@method_block
end
## before_compile hook as needed in ExtendProduct for Product
defmacro __before_compile__(_env) do
quote do
include_methods
end
end
end
end
end
## Service Code
defmodule Nectar.ExtendProduct do
## Makes DSL available defined in library code
use Nectar.ModelExtension
include_method do: (def fn_from_outside, do: "support function")
include_method do: (def get_name(product), do: product.name)
end
defmodule Nectar.Product do
...
# Add new support function here
## Make Service Code available to be consumed
## through Library Code
use Nectar.ExtendProduct
## Service Consumer Code
## not a direct macro
## @before_compile Nectar.ExtendProduct plays that role :)
...
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment