Behaviours in Elixir explained
Behaviours provide a way to define an interface which a module can implement. A module declares that it implements the Behaviour with the @behaviour
annotation. The functions in the modules implementing the behaviour will be checked at compile time to see if they match the function specifications in the behaviour and if it doesn't it throws an error.
Behaviours provide a way to:
- define a set of functions that have to be implemented by a module;
- ensure that a module implements all the functions in that set.
Defining behaviours
If a module adopts the behaviour of another module, then it will have to define all the functions defined in the module that is said to behave.
So in order to define the function specifications that a module needs to implement the @callback
directive is used
defmodule Greeter do
@callback shen_says_hello(String.t) :: any
@callback po_replies(String.t) :: any
end
Adopting a behaviour from another module
Modules adopting a behaviour will have to implement all the functions defined with the @callback
directive.
# A module uses the @behaviour annotation to indicate that it implements a behaviour
defmodule LordShenGreetsPo do
@behaviour Greeter
def shen_says_hello(name) do
IO.puts "Greetings, #{name}, we meet at last !!"
end
def po_replies(name) do
IO.puts "Hey, how ya doin'?, #{name}"
end
end
# Since the following module does not implement po_replies/1 a compile time warning will occur: "warning: undefined behaviour function po_replies/1 (for behaviour Greeter)"
defmodule LordShenGreetsPo do
@behaviour Greeter
def shen_says_hello(name) do
IO.puts "Greetings, #{name}, we meet at last !!"
end
end