Elixir v1.7がリリースされた
Tags: elixir, webdev, news
Published: 2018-10-02 07:26:34

---
title: Elixir v1.7がリリースされた
published: true
description: Elixir v1.7がリリースされました。本稿は2018年7月25日付blog記事「Elixir v1.7 released」にもとづいて、新しいおもな機能についてご説明します。ドキュメンテーションやエラーの扱い、ロガーレポート、さらにはExUnit、テスト用ライブラリなどにも改善が加えられました。
tags: #elixir, #webdev, #news
---

Elixir v1.7がリリースされました。本稿は2018年8月25日付blog記事「[Elixir v1.7 released](https://elixir-lang.org/blog/2018/07/25/elixir-v1-7-0-released/)」にもとづいて、新しいおもな機能についてご説明します。ドキュメンテーションやエラーの扱い、ロガーレポート、さらにはExUnit、テスト用ライブラリなどにも改善が加えられました。


# ドキュメンテーションのメタデータ
Elixir v1.7は[EEP 48](http://erlang.org/eep/eeps/eep-0048.html)を実装しています。Erlang VM上で動くすべての言語の間でドキュメントが互いに扱えるようにするためです。さらに、EEP 48では、ドキュメンテーションにメタデータで注釈をつけ、Elixirから活用できるようになります。

```elixir
@moduledoc "A brand new module"
@moduledoc authors: ["Jane", "Mary"], since: "1.4.0"
```

メタデータが与えられるのはつぎの3つです。

- [`@moduledoc`](https://hexdocs.pm/elixir/Module.html#module-moduledoc)
- [`@typedoc`](https://hexdocs.pm/elixir/Module.html#module-doc-and-typedoc)
- [`@doc`](https://hexdocs.pm/elixir/Module.html#module-doc-and-typedoc)

```elixir
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](https://hexdocs.pm/elixir/Behaviour.html)」モジュールをご覧ください。
- 関数やマクロ、コールバック、型には、それらの備わったバージョンが示されるようになりました。たとえば「[`defguard/1`](https://hexdocs.pm/elixir/Kernel.html#defguard/1)」の右端をご覧ください。
- 将来のElixirのバージョンは、ドキュメンテーションとサイドバーにガード用のセクションが含まれます(v1.8.0-dev「[Guards](https://hexdocs.pm/elixir/master/Kernel.html#guards)」参照)。現在ExDoc自体でこの機能を一般化する方法について議論しています(「[Arbitrary grouping of functions with `@doc group: :some_group`](https://github.com/elixir-lang/ex_doc/issues/876)」参照)

ElixirのインタラクティブシェルのIExも更新され、メタデータが出力されます。

![iex-metadata.png](https://elixir-lang.org/images/contents/iex-metadata.png)

Elixirはメタデータを与えることができます。ただし、ツールが使えるのは`:deprecated`と`:since`だけです。他のキーも将来表れるかもしれません。

改善されたのは標準ライブラリだけではありません。Elixirライブラリとアプリケーションずべてで使えます。将来はErlang VMのすべてのアプリケーションにまで広げられることが望まれます。

新しいドキュメンテーションのフォーマットを参照するには、[`Code.fetch_docs/1`](https://hexdocs.pm/elixir/Code.html#fetch_docs/1)をお使いください。ドキュメンテーションはとても重視されていて、構造化された情報を加えられることがその一歩です。


# \_\_STACKTRACE\_\_構造体
Erlang/OTP 21.0では、レキシカルスコープのスタックトレースの取り方が改められました。そのため、v1.6までのように`System.stacktrace/0`の副作用に頼らなくて済みます(v1.7から[`System.stacktrace/0`を使うことは推奨されません](https://hexdocs.pm/elixir/System.html#stacktrace/0))。

```elixir
try do
  ... something that may fail ...
rescue
  exception ->
    log(exception, System.stacktrace())
    reraise(exception, System.stacktrace())
end
```

v1.7では[`__STACKTRACE__/0`](https://hexdocs.pm/elixir/Kernel.SpecialForms.html#__STACKTRACE__/0)を使います。

```elixir
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`モジュール](http://erlang.org/documentation/doc-10.0-rc1/lib/kernel-6.0/doc/html/logger.html)が備わりました。Elixir v1.7はこのモジュールと完全に統合され、そのメタデータシステムが使えます。[`Logger.Translator`](https://hexdocs.pm/logger/Logger.Translator.html)のメカニズムもメタデータがエクスポートできるように改善され、カスタム`Logger`のバックエンドでつぎのような情報が使えます(「Logger」「[Metadata](https://hexdocs.pm/logger/Logger.html#module-metadata)」参照)。

- `:crash_reason`: 2要素のタプルで、第1要素がスロー/エラー/終了した理由、第2要素はスタックトレースです。
- `:initial_call`: プロセスを始めた最初の呼び出しです。
- `:registered_name`: プロセスに登録された名前のアトムです。

これまでErlangの`:error_logger`にフックしていたElixirライブラリは、`Logger`に切り替えた方がよいでしょう。これからのErlang/OTPバージョンがサポートできるからです。


# ロガーのコンパイル時のパージ
これまで`Logger`のマクロ[`debug/2`](https://hexdocs.pm/logger/Logger.html#debug/2)や[`info/2`](https://hexdocs.pm/logger/Logger.html#info/2)などは、ログがなくても引数を評価しました。Elixir v1.7から引数は、メッセージログがあったときのみ評価されます。

また、Loggerの設定システムに、新たなオプションとして`:compile_time_purge_matching`が加わりました。特定のコンパイル時メタデータをもつログが除けます。たとえば、つぎの設定はアプリケーション`:foo`のレベルが`:info`より低いか、あるいは`Bar.foo/3`からのすべてのロガーの呼び出しを削除します。

```elixir
config :logger,
  compile_time_purge_matching: [
    [application: :foo, level_lower_than: :info],
    [module: Bar, function: "foo/3"]
  ]
```


# ExUnitの改善
[ExUnit](https://hexdocs.pm/ex_unit/)はElixirのユニットテストのライブラリです。Elixirのマクロを使って、失敗が起こったときの詳しいエラーレポートを表示します。たとえば、つぎのコードは失敗します。

```elixir
assert "fox jumps over the lazy dog" == "brown fox jumps over the dog"
```

このとき表示されるのがつぎのレポートです。

![exunit-diff.png](https://elixir-lang.org/images/contents/exunit-diff.png)

[`assert/1`マクロ](https://hexdocs.pm/ex_unit/ExUnit.Assertions.html#assert/1)は、コードを見て、現在のファイルと行、およびオペランドを取り出します。そのうえで、`assert`が失敗したときスタックトレースとともに、データ構造の差分を表示します。

ただ、`assert some_function(expr1, var2)`のようなコードが失敗したとき、通常はテストをし直してふたつの変数をデバッグしたり、出力しなければなりませんでした。Elixir v1.7では、「素の」`assert`が失敗したときは、それぞれの引数の値が出力されます(「[Show arguments in ExUnit reports for non-operator matches](https://github.com/elixir-lang/elixir/commit/eb5e809f10b4a24215d21cb109b506c2cf9f1761)」参照)。たとえば、つぎのレポートは単純な`assert some_vars(1 + 2, 3 + 4)`の場合です。

![exunit-bare-assertion-diff.png](https://elixir-lang.org/images/contents/exunit-bare-assertion-diff.png)

また、[`doctest/2`](https://hexdocs.pm/ex_unit/master/ExUnit.DocTest.html#doctest/2)の失敗はカラー化され、違いが示されます(「[Add diff to doctest](https://github.com/elixir-lang/elixir/pull/7585)」参照)。

ExUnitはテストフレームワークで、Mixはビルドツールです。開発者は通常`mix test`を呼び出してテストします。

`mix test`には新たに`--failed`フラグが加わり、前回のテストのうち失敗したものだけをすべて実行できます(「[Add support for "--failed" in ExUnit](https://github.com/elixir-lang/elixir/pull/7373)」参照)。また、`mix test --cover`で、つぎのような情報がカバレッジレポートとしてまとめて表示されます(「[Display simple coverage report to console](https://github.com/elixir-lang/elixir/pull/7664)」参照)。

```terminal
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はこれからも改定が重ねられます。その他に加えられた詳しい変更点のリストは[リリースノート](https://github.com/elixir-lang/elixir/releases/tag/v1.7.0)でご覧ください。また、つぎのv1.8に加えられる変更は「[Changelog for Elixir v1.8](https://github.com/elixir-lang/elixir/blob/master/CHANGELOG.md)」に記載されます。

Elixirのコードベースに直接は関わらない部分でも重要な改善があります。

- webサイトに「[Development](https://elixir-lang.org/development.html)」のセクションを加えました。Elixirのチームの構成と目標を説明しています。
- [Honeypot](https://www.honeypot.io/)によるドキュメンタリー短編映像「[Elixir: A Mini-Documentary](http://doc.honeypot.io/elixir-documentary-2018/?utm_source=elixir_home&utm_medium=referral)」(12:48)を加えました。
- すでにExDocツールの改善についてはご説明しました。もうひとつ、シンタックスハイライトがElixir自身に[Makeupライブラリ](https://github.com/tmbb/makeup)により備わったことをつけ加えておきます。これにより、文法やスタイルについてのコントロールが増し、ロード時間も改善されました。

2018年9月4日から7日までワシントン州ベルビューで開かれた[ElixirConf](https://elixirconf.com/)では、José Valim氏が基調講演でElixirの「[The Next Five Years](https://www.youtube.com/watch?v=suOzNeMJXl0)」と題してお話しされました。