@behaviour and defdelegate

Hi

I have an Application that keeps a behaviour definition for its interface (to improve testing of its clients by creating a test stub that implements the same interface). The behaviour looks like:

defmodule Register.DocEvents do
  defmacro __using__(_) do
    quote do
      @behaviour Register.DocEvents
    end
  end

  @callback initialize(soure :: atom()) :: :ok | {:error, String.t()}
  ...
end

I then implement the same behaviour for the Application like:

defmodule Register do
  use Register.DocEvents

  @impl Register.DocEvents
  def initialize(source) do
    Register.Server.initialize(Register.Server, source)
  end
  ...
end

But I would like to do like this instead:

defmodule Register do
  use Register.DocEvents

  @impl Register.DocEvents
  defdelegate initialize(source), to: Register.Server
  ...
end

It seems to work when I test, but I do not now if this could lead to any other negative effects?

Br Patrik

A couple of comments:

  1. Using use just to specify a behaviour is, I think, much less clear than simply specifying @behaviour Register.DocEvents

  2. defdelegate is a macro that does nothing more than:

def initialize(source) do
  Register.Server.initialize(source)
end

so you should not have any unexpected side affects.

  1. You might look into @defoverridable in your behaviour module which would then allow you to have a default implementation that you don’t need to delegate to
3 Likes

Thx for quick reply! :slight_smile: