DEV Community

gumi TECH for gumi TECH Blog

Posted on

Elixir v1.7がリリースされた

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"
Enter fullscreen mode Exit fullscreen mode

メタデータが与えられるのはつぎの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
Enter fullscreen mode Exit fullscreen mode

ExDocツールを更新して、開発者に向けたよりよいドキュメントにメタデータが活かせるようになりました。改善されたのはおもにつぎの3つの点です。

  • 推奨されないモジュールや関数、コールバック、型には自動的に警告が出ます。たとえば非推奨になった「Behaviour」モジュールをご覧ください。
  • 関数やマクロ、コールバック、型には、それらの備わったバージョンが示されるようになりました。たとえば「defguard/1」の右端をご覧ください。
  • 将来のElixirのバージョンは、ドキュメンテーションとサイドバーにガード用のセクションが含まれます(v1.8.0-dev「Guards」参照)。現在ExDoc自体でこの機能を一般化する方法について議論しています(「Arbitrary grouping of functions with @doc group: :some_group」参照)

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

iex-metadata.png

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
Enter fullscreen mode Exit fullscreen mode

v1.7では__STACKTRACE__/0を使います。

try do
  ... something that may fail ...
rescue
  exception ->
    log(exception, __STACKTRACE__)
    reraise(exception, __STACKTRACE__)
end
Enter fullscreen mode Exit fullscreen mode
  • __STACKTRACE__: 現在扱っている例外のスタックトレースを返します。try/1式のcatchrescue句でのみ使えます。

この変更により、将来はパフォーマンスも高められます。レキシカルスコープではスタックトレースがいつ使われたか正確に追跡でき、try構造が終了したらスタックトレースの中身を参照し続けずに済むからです。

例外システムのほかの部分も改善しました。たとえば、ArgumentErrorArithmeticErrorおよび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/2info/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"]
  ]
Enter fullscreen mode Exit fullscreen mode

ExUnitの改善

ExUnitはElixirのユニットテストのライブラリです。Elixirのマクロを使って、失敗が起こったときの詳しいエラーレポートを表示します。たとえば、つぎのコードは失敗します。

assert "fox jumps over the lazy dog" == "brown fox jumps over the dog"
Enter fullscreen mode Exit fullscreen mode

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

exunit-diff.png

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)の場合です。

exunit-bare-assertion-diff.png

また、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
Enter fullscreen mode Exit fullscreen mode

まとめ

このリリースは注目される新機能より、品質の改善が重視されました。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」と題してお話しされました。

Top comments (0)