gumi TECH
Posted on October 2, 2018
Elixir v1.7がリリースされました。本稿は2018年8月25日付blog記事「Elixir v1.7 released」にもとづいて、新しいおもな機能についてご説明します。ドキュメンテーションやエラーの扱い、ロガーレポート、さらにはExUnit、テスト用ライブラリなどにも改善が加えられました。
ドキュメンテーションのメタデータ
Elixir v1.7はEEP 48を実装しています。Erlang VM上で動くすべての言語の間でドキュメントが互いに扱えるようにするためです。さらに、EEP 48では、ドキュメンテーションにメタデータで注釈をつけ、Elixirから活用できるようになります。
@moduledoc "A brand new module"
@moduledoc authors: ["Jane", "Mary"], since: "1.4.0"
メタデータが与えられるのはつぎの3つです。
defmodule MyModule do
@typedoc "This type"
@typedoc since: "1.1.0"
@type t :: term
@doc "Hello world"
@doc since: "1.1.0"
def hello do
"world"
end
@doc """
Sums `a` to `b`.
"""
def sum(a, b) do
a + b
end
end
ExDocツールを更新して、開発者に向けたよりよいドキュメントにメタデータが活かせるようになりました。改善されたのはおもにつぎの3つの点です。
- 推奨されないモジュールや関数、コールバック、型には自動的に警告が出ます。たとえば非推奨になった「Behaviour」モジュールをご覧ください。
- 関数やマクロ、コールバック、型には、それらの備わったバージョンが示されるようになりました。たとえば「
defguard/1
」の右端をご覧ください。 - 将来のElixirのバージョンは、ドキュメンテーションとサイドバーにガード用のセクションが含まれます(v1.8.0-dev「Guards」参照)。現在ExDoc自体でこの機能を一般化する方法について議論しています(「Arbitrary grouping of functions with
@doc group: :some_group
」参照)
ElixirのインタラクティブシェルのIExも更新され、メタデータが出力されます。
Elixirはメタデータを与えることができます。ただし、ツールが使えるのは:deprecated
と:since
だけです。他のキーも将来表れるかもしれません。
改善されたのは標準ライブラリだけではありません。Elixirライブラリとアプリケーションずべてで使えます。将来はErlang VMのすべてのアプリケーションにまで広げられることが望まれます。
新しいドキュメンテーションのフォーマットを参照するには、Code.fetch_docs/1
をお使いください。ドキュメンテーションはとても重視されていて、構造化された情報を加えられることがその一歩です。
__STACKTRACE__構造体
Erlang/OTP 21.0では、レキシカルスコープのスタックトレースの取り方が改められました。そのため、v1.6までのようにSystem.stacktrace/0
の副作用に頼らなくて済みます(v1.7からSystem.stacktrace/0
を使うことは推奨されません)。
try do
... something that may fail ...
rescue
exception ->
log(exception, System.stacktrace())
reraise(exception, System.stacktrace())
end
v1.7では__STACKTRACE__/0
を使います。
try do
... something that may fail ...
rescue
exception ->
log(exception, __STACKTRACE__)
reraise(exception, __STACKTRACE__)
end
-
__STACKTRACE__
: 現在扱っている例外のスタックトレースを返します。try/1
式のcatch
とrescue
句でのみ使えます。
この変更により、将来はパフォーマンスも高められます。レキシカルスコープではスタックトレースがいつ使われたか正確に追跡でき、try
構造が終了したらスタックトレースの中身を参照し続けずに済むからです。
例外システムのほかの部分も改善しました。たとえば、ArgumentError
やArithmeticError
およびKeyError
のメッセージにより多くの情報が示されます。
Erlang/OTPのロガーとの統合
Erlang/OTP 21には新しい:logger
モジュールが備わりました。Elixir v1.7はこのモジュールと完全に統合され、そのメタデータシステムが使えます。Logger.Translator
のメカニズムもメタデータがエクスポートできるように改善され、カスタムLogger
のバックエンドでつぎのような情報が使えます(「Logger」「Metadata」参照)。
-
:crash_reason
: 2要素のタプルで、第1要素がスロー/エラー/終了した理由、第2要素はスタックトレースです。 -
:initial_call
: プロセスを始めた最初の呼び出しです。 -
:registered_name
: プロセスに登録された名前のアトムです。
これまでErlangの:error_logger
にフックしていたElixirライブラリは、Logger
に切り替えた方がよいでしょう。これからのErlang/OTPバージョンがサポートできるからです。
ロガーのコンパイル時のパージ
これまでLogger
のマクロdebug/2
やinfo/2
などは、ログがなくても引数を評価しました。Elixir v1.7から引数は、メッセージログがあったときのみ評価されます。
また、Loggerの設定システムに、新たなオプションとして:compile_time_purge_matching
が加わりました。特定のコンパイル時メタデータをもつログが除けます。たとえば、つぎの設定はアプリケーション:foo
のレベルが:info
より低いか、あるいはBar.foo/3
からのすべてのロガーの呼び出しを削除します。
config :logger,
compile_time_purge_matching: [
[application: :foo, level_lower_than: :info],
[module: Bar, function: "foo/3"]
]
ExUnitの改善
ExUnitはElixirのユニットテストのライブラリです。Elixirのマクロを使って、失敗が起こったときの詳しいエラーレポートを表示します。たとえば、つぎのコードは失敗します。
assert "fox jumps over the lazy dog" == "brown fox jumps over the dog"
このとき表示されるのがつぎのレポートです。
assert/1
マクロは、コードを見て、現在のファイルと行、およびオペランドを取り出します。そのうえで、assert
が失敗したときスタックトレースとともに、データ構造の差分を表示します。
ただ、assert some_function(expr1, var2)
のようなコードが失敗したとき、通常はテストをし直してふたつの変数をデバッグしたり、出力しなければなりませんでした。Elixir v1.7では、「素の」assert
が失敗したときは、それぞれの引数の値が出力されます(「Show arguments in ExUnit reports for non-operator matches」参照)。たとえば、つぎのレポートは単純なassert some_vars(1 + 2, 3 + 4)
の場合です。
また、doctest/2
の失敗はカラー化され、違いが示されます(「Add diff to doctest」参照)。
ExUnitはテストフレームワークで、Mixはビルドツールです。開発者は通常mix test
を呼び出してテストします。
mix test
には新たに--failed
フラグが加わり、前回のテストのうち失敗したものだけをすべて実行できます(「Add support for "--failed" in ExUnit」参照)。また、mix test --cover
で、つぎのような情報がカバレッジレポートとしてまとめて表示されます(「Display simple coverage report to console」参照)。
Generating cover results ...
Percentage | Module
-----------|--------------------------
100.00% | Plug.Exception.Any
100.00% | Plug.Adapters.Cowboy2.Stream
100.00% | Collectable.Plug.Conn
100.00% | Plug.Crypto.KeyGenerator
100.00% | Plug.Parsers
100.00% | Plug.Head
100.00% | Plug.Router.Utils
100.00% | Plug.RequestId
... | ...
-----------|--------------------------
77.19% | Total
まとめ
このリリースは注目される新機能より、品質の改善が重視されました。Elixirはこれからも改定が重ねられます。その他に加えられた詳しい変更点のリストはリリースノートでご覧ください。また、つぎのv1.8に加えられる変更は「Changelog for Elixir v1.8」に記載されます。
Elixirのコードベースに直接は関わらない部分でも重要な改善があります。
- webサイトに「Development」のセクションを加えました。Elixirのチームの構成と目標を説明しています。
- Honeypotによるドキュメンタリー短編映像「Elixir: A Mini-Documentary」(12:48)を加えました。
- すでにExDocツールの改善についてはご説明しました。もうひとつ、シンタックスハイライトがElixir自身にMakeupライブラリにより備わったことをつけ加えておきます。これにより、文法やスタイルについてのコントロールが増し、ロード時間も改善されました。
2018年9月4日から7日までワシントン州ベルビューで開かれたElixirConfでは、José Valim氏が基調講演でElixirの「The Next Five Years」と題してお話しされました。
Posted on October 2, 2018
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.