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