Skip to content

Instantly share code, notes, and snippets.

@stefanluptak
Last active January 2, 2025 15:19
Show Gist options
  • Save stefanluptak/d860757753247f8b50c1155435e6e05d to your computer and use it in GitHub Desktop.
Save stefanluptak/d860757753247f8b50c1155435e6e05d to your computer and use it in GitHub Desktop.
# before Elixir 1.18 (without defdelegate)
defmodule NameBehaviour do
@callback name :: String.t() | :leave_me_alone
@optional_callbacks [name: 0]
end
defmodule Greeter do
defmacro __using__(_opts) do
quote do
@behaviour NameBehaviour
def name, do: nil
def greet do
case name() do
nil -> "Hello stranger"
:leave_me_alone -> "Sorry..."
name -> "Hello " <> name
end
end
defoverridable name: 0
end
end
end
defmodule John do
use Greeter
def name do
"John"
end
end
defmodule Alice do
use Greeter
def name do
:leave_me_alone
end
end
defmodule Bob do
use Greeter
end
iex> John.greet()
"Hello John"
iex> Alice.greet()
"Sorry..."
iex> Bob.greet()
"Hello stranger"
# before Elixir 1.18 (with defdelegate)
defmodule NameBehaviour do
@callback name :: String.t() | :leave_me_alone
@optional_callbacks [name: 0]
end
defmodule Greeter do
defmacro __using__(_opts) do
quote do
@behaviour NameBehaviour
defdelegate name, to: unquote(__MODULE__)
def greet do
case name() do
nil -> "Hello stranger"
:leave_me_alone -> "Sorry..."
name -> "Hello " <> name
end
end
defoverridable name: 0
end
end
def name, do: nil
end
defmodule John do
use Greeter
def name do
"John"
end
end
defmodule Alice do
use Greeter
def name do
:leave_me_alone
end
end
defmodule Bob do
use Greeter
end
iex> John.greet()
"Hello John"
iex> Alice.greet()
"Sorry..."
iex> Bob.greet()
"Hello stranger"
# after Elixir 1.18
defmodule NameBehaviour do
@callback name :: String.t() | :leave_me_alone
@optional_callbacks [name: 0]
end
defmodule Greeter do
defmacro __using__(_opts) do
quote do
@behaviour NameBehaviour
end
end
def greet(module) do
if Code.ensure_loaded?(module) and function_exported?(module, :name, 0) do
case module.name() do
:leave_me_alone -> "Sorry..."
name -> "Hello " <> name
end
else
"Hello stranger"
end
end
end
defmodule John do
use Greeter
def name do
"John"
end
end
defmodule Alice do
use Greeter
def name do
:leave_me_alone
end
end
defmodule Bob do
use Greeter
end
iex> Greeter.greet(John)
"Hello John"
iex> Greeter.greet(Alice)
"Sorry..."
iex> Greeter.greet(Bob)
"Hello stranger"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment