When implementing the callback function, does it override the original implementation of the function?

As per OTP guide

The idea is to divide the code for a process in a generic part (a behaviour module) and a specific part (a callback module ).

So, will this piece of code, mainly the callbacks (init, handle_cast and handle_call)

defmodule Stack do
  use GenServer

  def start_link(state) do
    GenServer.start_link(__MODULE__, state, name: __MODULE__)
  end

  ## Callbacks

  @impl true
  def init(stack) do
    {:ok, stack}
  end

  @impl true
  def handle_call(:pop, _from, [head | tail]) do
    {:reply, head, tail}
  end

  @impl true
  def handle_cast({:push, head}, tail) do
    {:noreply, [head | tail]}
  end
end

override the default implementation of those function in Supervisior module?

For eg, Will this init function be overriden ?

def init(children, options) when is_list(children) and is_list(options) do
    unless strategy = options[:strategy] do
      raise ArgumentError, "expected :strategy option to be given"
    end

    intensity = Keyword.get(options, :max_restarts, 3)
    period = Keyword.get(options, :max_seconds, 5)
    flags = %{strategy: strategy, intensity: intensity, period: period}
    {:ok, {flags, Enum.map(children, &init_child/1)}}
  end

The issue here is that your code has use GenServer but in your post you are talking about Supervisor code. Those are different modules. Your code overrides functions, yes, but not in Supervisor. Instead it overrides functions from the GenServer behaviour that you can find here: https://github.com/elixir-lang/elixir/blob/v1.9.1/lib/elixir/lib/gen_server.ex#L738-L821

The overriding of functions also isn‘t related to behaviours/callback modules, but it‘s done with elixirs metaprogramming, which does implement default clauses for otherwise required callbacks.

Your example also doesn‘t match, because the callbacks are init/1, while the function you posted the code of is init/2, which on the beam are two totally different functions.

2 Likes