I had attempted to the following usage:
iex(1)> defmodule MyApp.Calculator do
...(1)> @behaviour __MODULE__
...(1)> @callback add(integer(), integer()) :: integer()
...(1)> def add(x, y), do: x + y
...(1)> end
warning: behaviour MyApp.Calculator is undefined
After some discussion with Muskala (micmus)/Milde (lostkobrakai) it seemed that use case may be possibly be valid. That is, the ability to define and implement a behaviour in the same module.
For my part, I had wanted to locate the documentation and @callback along with the default implementation. I have been diligently factoring my modules into separate files per
http://blog.plataformatec.com.br/2015/10/mocks-and-explicit-contracts/. With this approach, however, I am finding that there has been a bit of an explosion with the number of files.
It was suggested that the following is considered an idiomatic way to associate doc with an implementation:
defmodule MyApp.Calculator do
@callback add(integer(), integer()) :: integer()
defmacro __using__ do
quote do
def add(x, y), do: x + y
end
end
end
defmodule MyApp.CalculatorImpl do
use MyApp.Calculator
@behaviour MyApp.Calculator
end
But here too I need to define a second file for the default implementation (assuming one module definition per file is desired). I find that there is also a bit of additional complexity here which makes it slightly more difficult to reason about.
Note: Related?
https://groups.google.com/forum/#!topic/elixir-lang-core/8jrwjECcFTwJack