Elixir v1.6.0 について
まだ正式なリリースはされていませんが https://github.com/elixir-lang/elixir で v1.6.0 に向けた機能が現在進行形で開発されています。現行の最新版は v1.5.2 です。
master ブランチのドキュメントはここで更新され続けています。
今回はこのうち v1.6.0 に入るであろう新機能のうち二つ
- Mix Format
- Dynamic Supervisor
について紹介します。
Mix Format(Code Formatter)
Elixir を書いていて一番困ることの一つは公式の code formatter がないことです。
インデントずれや引数なし関数の()
忘れを指摘するのは本来はヒトのやることではないです。機械にできることは機械がやってもらうのがベストです。
サードパーティのcode formatter としては ex_format や exfmt などがありましたが、スタイルガイドに厳密でなかったりコメントアウトが消えてしまうなどの不具合があり、実戦投入をするにはまだ早いかな、という感触のあるものでした。
Elixir-1.6.0 dev では Code.format_string!/2 という関数を通してプロジェクト全体のフォーマットが行えるようになります。
処理としてはstringをinputとしてCode.Formatter.algebra!
によって AST に分解し、持っているフォーマット情報に基づいてInspect.Algebra.format/2
によってstringに組み立て直す、ということをしています (ソースコード参照)
使い方
$ mix format /path/to/file.ex
で指定のファイルのフォーマットを行えます。
また .formatter.exs
に設定ファイルを記述して、プロジェクト全体のフォーマット規約をカスタマイズすることができます。
[
inputs: [
"lib/*/{lib,unicode,test}/**/*.{ex,exs}",
"lib/*/mix.exs"
],
locals_without_parens: [
# Formatter tests
assert_format: 2,
assert_format: 3,
assert_same: 1,
assert_same: 2,
# Errors tests
assert_eval_raise: 3,
# Mix tests
in_fixture: 2,
in_tmp: 2
]
]
それから
$ mix format
を行うと inputs:
で指定されたコードがフォーマットされます。
既存の aliases 機能を用いて
defp aliases() do
{xxxx: ["format", "release"]}
end
などとしてビルド時など任意のタスクと一緒に format を噛ませるのもいいでしょう。
また--check-formatted
オプションを付けると不正なフォーマットのファイルの存在をチェックすることができます。 (不正なファイルがあると exit 0 を吐きます) これはCIでの運用が有用だと思われます。
Dynamic Supervisor
Dynamic Supervisor は子プロセスを動的に追加することができる supervisor の新しいビヘイビアです。
:simple_one_for_one
の代替となるものです。既存の :simple_one_for_one
再起動戦略を持ったプロジェクトを Elixir 1.6.0 に上げる場合は Dynamic Supervisor に入れ替える必要があります。
children の指定なしで起動してあとで任意のタイミングで start_child/2
させることができます。
Dynamic Supervisor は children の link なしで start_link します。現在サポートしている戦略は :one_for_one
のみのようです。
使ってみます。 Dynamic Supervisor を起動します。
iex> {:ok, sup} = DynamicSupervisor.start_link(strategy: :one_for_one)
{:ok, #PID<0.85.0>}
子を動的に追加します。
iex> {:ok, agent1} = DynamicSupervisor.start_child(sup, {Agent, fn -> %{} end})
{:ok, #PID<0.87.0>}
もう一つ追加します。
iex> {:ok, agent2} = DynamicSupervisor.start_child(sup, {Agent, fn -> %{} end})
{:ok, #PID<0.89.0>}
iex> DynamicSupervisor.count_children(sup)
%{active: 2, specs: 2, supervisors: 0, workers: 2}
:simple_one_for_one
を使うときと感触は変わりません。が、 :one_for_one
以外の strategy が追加された場合どのような挙動になるのかも気になるところです。
ただモジュールベースでDynamic
なことが明示されているので、それぞれの supervisor の strategy を把握しやすくなり、扱いやすくなったように感じます。
まとめ
Elixir は現在非常に活発に開発が進んでいる言語です。(そのベースとなっている Erlang/OTP もです)
ぜひ GitHub を追ったり Elixir Conf の資料を見て最新の動向を追い、その素晴らしい機能をフルに活用しましょう。
Top comments (0)