How to use defdelegate

We use defdelegate when we want a function in module A to have the same behavior of other function in module B. (Is the equivalent of calling function B directly but from another module) This decoupling of functions can help us to create a public API, for the users of module A just have to call the functions inside module A, and the implementation details can be done under the hood in module B.

defmodule Calculator do

  alias Cache.Fibonacci

  defdelegate start, to: Fibonacci
  defdelegate calculate_fib(n), to: Fibonacci, as: :get_fib

  end
end

In the first defdelegate we delegate the function Calculator.start to a function (with the same name) in the module Cache.Fibonacci. (Remember alias turns “Cache.Fibonacci” into “Fibonacci”)

If you saw that first example only you would think that we don’t have to worry about arguments, but that’s not true, only if the functions have zero arguments you can skip the function(args) notation.

The second defdelegate, delegates calculate_fib(n) to the function get_fib inside the Cache.Fibonacci module

Now, you can’t do pattern matching in defdelegate you can only pass arguments, so if you have some sort of pattern matching you have to pass several arguments like this:

defmodule Calculator do

  alias Cache.Fibonacci

  defdelegate start, to: Fibonacci
  defdelegate calculate_fib(n), to: Fibonacci, as: :get_fib
  defdelegate calculate_fib(n, dict), to: Fibonacci, as: :get_fib

end

 

This is the Cache.Fibonacci module, you can see how that the “dict” parameter is eventually pattern matched to %{key: “value”}

defmodule Cache.Fibonacci do

@me __MODULE__

#Public API
def start() do
    Agent.start_link(fn -> %{0 => 0, 1 => 1} end, name: @me)
end

def get_fib(n) do
fib(n, in_map?(n))
end

def get_fib(n, %{key: "value"}) do
n
end

...

end

Why did I create this Website?

Hi! I’m Carlos Sisnett

I’ve been interested in programming for some time, but I just recently found out about elixir a month ago.

I got really excited and somewhat nervous because I was learning Django when I first encountered elixir, so I had to make a choice between staying in my current path (comfortable) or doing something more rewarding(and riskier).

I decided to take the leap of faith and focus on learning elixir/phoenix.

I really believe that the best person to teach somebody is the one who is just one step ahead, so I hope I can help people learning elixir as others have helped me while on this journey.

My goal with this website is to make it as easy as possible for people (especially newbies) to be productive in elixir, therefore the name Productive Elixir.

I’m interested in knowing what you thought of elixir before being sold.

If you’re not sold on elixir, see these posts so you can make up your own mind: What is Elixir? An Introduction and Why use Elixir?