Open2
Elixir callback, behaviour, 共通処理化の習作
同じような処理をするモジュールがある
- 基本的な処理は1つ
- たまに違う処理にしたい
- たまに基本的な処理も使って違う処理にしたい
で考えてみたコード例
// 注意:著者はElixir業務経験なしです。
defmodule Worker do
@callback run :: :ok
def run do
IO.puts "base function"
:ok
end
def commons(args \\ []) do
excepts = Keyword.get(args, :except, [])
quote do
if not Enum.member?(unquote(excepts), :run) do
defdelegate run, to: Worker
end
end
end
defmacro __using__(which) when is_atom(which) do
apply(__MODULE__, which, [])
end
defmacro __using__({which, args}) when is_atom(which) do
apply(__MODULE__, which, [args])
end
end
defmodule AWorker do
@behaviour Worker
use Worker, :commons
end
defmodule BWorker do
@behaviour Worker
use Worker, {:commons, except: [:run]}
@impl true
def run do
IO.puts "My Runner"
:ok
end
end
defmodule CWorker do
@behaviour Worker
use Worker, {:commons, except: [:run]}
@impl true
def run do
Worker.run()
IO.puts "My Runner with base function"
:ok
end
end
AWorker.run()
BWorker.run()
CWorker.run()
たまに基本的な処理も使って追加したい
これは欲張りすぎで機能分割(run
を細かく)して、run
自体は使わない方が真っ当かもしれない