trySwiftConfにて、protocolの話がかなり熱かったのでElixirのprotocolの動作を思い出し込みで確認してみました。
テストコードありなので、以下をそのままファイルに書き出して実行すると現状の動作を確認できます。
ポイントは、
- 継承
- defprotocolとdefimpの組み合わせ
です。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Value do | |
| defmacro __using__(_opts) do | |
| quote do | |
| def one, do: 1 | |
| def three, do: 2 | |
| defoverridable [one: 0, three: 0] | |
| end | |
| end | |
| end | |
| defmodule MyValue do | |
| use Value | |
| defstruct [my_value: "this is my_value struct"] | |
| def one, do: super | |
| def three, do: 1 + super | |
| end | |
| # combine with defmodule | |
| defprotocol Value do | |
| @fallback_to_any true # default false | |
| def zero?(val) | |
| end | |
| defimpl Value, for: Atom, do: def zero?(_atom), do: :zero | |
| defimpl Value, for: Integer, do: def zero?(_integer), do: 0 | |
| defimpl Value, for: MyValue, do: def zero?(struct), do: "sample for struct" | |
| defimpl Value, for: Any, do: def zero?(_any), do: [0, "zero"] | |
| # run test | |
| # $ elixir this_file.ex | |
| ExUnit.start | |
| defmodule MyValueTests do | |
| use ExUnit.Case | |
| alias MyValue | |
| alias Value | |
| test "inheritance" do | |
| assert MyValue.one == 1 | |
| assert MyValue.three == 3 | |
| end | |
| test "defprotcol and defimpl" do | |
| assert Value.zero?(:atom) == :zero | |
| assert Value.zero?(0) == 0 | |
| assert Value.zero?("any") == [0, "zero"] | |
| assert Value.zero?(%MyValue{}) == "sample for struct" | |
| end | |
| end |