[Elixir]ExUnitで同名のtestが存在した時にコンパイルエラーにする

1行まとめ ExUnitにおけるテストケースの重複時にコンパイルエラーにしたい場合、 test_helper.exs に Code.compiler_options(warnings_as_errors: true) オプションを追加しておこう 多分、これはチーム開発では大いに役立ちます ExUnitが test マクロを関数定義するまで 以下のようなテストケースがあったとします。 この時、 test マクロで定義されたところは __ErrorSampleExunitTest__.’:test the truth’ としてコンパイル時に定義されます。 Elixir1.2.1では以下の行での話になります。 https://github.com/elixir-lang/elixir/blob/v1.2.1/lib/ex_unit/lib/ex_unit/case.ex#L258 同名の test が存在した場合 さて、この時に複数の同名のテストが存在した場合はどうでしょう? 例えば以下。 この場合、コンパイル時にCLIで以下のような warn が表示されます。 test/error_sample_exunit_test.exs:8: warning: this clause cannot match because a previous clause at line 4 always matches テストケースを記述するコードは、 .exs の拡張子を持つので、このようなwarnはテスト実行毎に表示されます。なので、実行を注意深く見ていると、このエラーを知ることができます。 ただ、他のテスト自体は実行されます。 コンパイルエラーにする ただ、warnではなくコンパイルエラーにしたほうが親切なのでは?と思い、手元でコンパイルエラーになるようにExUnitを直接修正してみました。 ExUnitのtestマクロでは、以下の2点でコンパイル時に関数を定義します。 https://github.com/elixir-lang/elixir/blob/v1.2.1/lib/ex_unit/lib/ex_unit/case.ex#L258 https://github.com/elixir-lang/elixir/blob/v1.2.1/lib/ex_unit/lib/ex_unit/case.ex#L280 なので、その直前で以下のように既存モジュールに定義済みの同名関数があるかどうかを検出させ、trueであればraiseするようにします。 コンパイラオプションで回避する…More

[Elixir]CustomLoggerのコードを追う

[Elixir]Loggerのconsole出力をファイルに書き出すではlogger_file_backendを使う、ところを残しました。そのついでに、CustomLogger付近とその作り方を見てみました。 参考: Elixir Meetup #1 Loggerの構造と拡張 from Sugawara Genki これを理解するために、ElixirのLoggerの実装群や、 GenEvent 付近が理解を助けてくれます。 https://github.com/elixir-lang/elixir/tree/v1.2.0/lib/logger/lib Elixir本体のloggerの参考 https://github.com/elixir-lang/elixir/blob/v1.2.0/lib/logger/lib/logger/backends/console.ex :console のbackendの書き方の参考 このようにしてcustomer loggerを作り、backendとして指定、利用できる https://github.com/elixir-lang/elixir/blob/v1.2.0/lib/logger/lib/logger/formatter.ex log levelの種類によって表示を整形する参考 https://github.com/elixir-lang/elixir/blob/v1.2.0/lib/elixir/lib/gen_event.ex Backendの拡張のために利用される 私も参考で貼ったスライドを参考に、練習のためにCustomLoggerを書いてみました。consoleの実装箇所を参考にすればここら辺もかける感じ。 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…More

[Elixir]Loggerのconsole出力をファイルに書き出す

少しLogに関する知見を得たので、 logger_file_backend とか使ってみることにしました。後でちゃんとCustomLoggerの知見を貯めておこう。 経緯 通常、Loggerはconsoleに書き出されます。しかし、そのままではIOが大変ですし、ファイルに書き出したりしていきたいです。そのため、ログをファイル出力する形にしたいなーと考えていました。 CustomLogger ElixirのLogger のドキュメントを少し読んでみると、デフォルトでは :console としてコンソールに結果が出力され、そこからカスタムするときはCustomLoggerを作れるよ、と書いています。 Custom backends を読んでみると、 GenEvent を使ってCustomLoggerを作ることができるのですね。そこで簡単なファイルへ書き出すCustomLoggerを作ろうとは思ったのですが、通常のLoggerの結果をファイルに書き出す、というシンプルなreposirotyを見つけたので、ひとまずはそれを使ってみることにしました。 Logger_file_backend Logger_file_backend https://hex.pm/packages/logger_file_backend https://github.com/onkel-dirtus/logger_file_backend 他に、Erlangのlagerをラップしたexlagerというのもあるのですが、Phoenixと一緒に使う方法とか探しているとElixirに組み込まれているLoggerを操作する系の方が安易だったので見送りました。 exloger https://github.com/khia/exlager 参考 elixir in production from Tsunenori Oohara 導入した時の、サンプルプロジェクトのコミット https://github.com/KazuCocoa/web_qa_vote/commit/035f5cd6e451cd84d5c3e4304cc0853e8ccf0672More

[Elixir]tear down in ExUnit as on_exit

teardownを探していたのですが、 ExUnit では、現在はteardownは on_exit のcallbackで実装されています。過去、この形に変更されたのですね。 http://elixir-lang.org/docs/v1.1/ex_unit/ExUnit.Callbacks.html#on_exit/2 使い方は以下。 setup の中で on_exit を定義します。これで、この setup_all や setup と同じサイクルで処理が実施されます。 ちなみに、 shouldi を使った時は上手く動作しなかった… 過去、私も書いていた… MIX AND OTP vol 1More

[Elixir]compile timeに決定されるモジュールの定数

Elixirでは以下のように @neko と定義することで、このモジュール内で共通して使える要素を定義できます。最近使い方を誤ってしまったのですが、この値はコンパイル時に決定されるので、それ以降に読まれる値を設定することはできません。 In other words, the value is read at compilation time and not at runtime. As we are going to see, this makes attributes useful to be used as storage during module compilation. http://elixir-lang.org/getting-started/module-attributes.html 例えば、 というような用途では、必ず default が代入されます。 つい忘れていてつまづいたので、メモ…More

[Elixir][Jupyter]Play IElixir on Jupyter

最近、Jupyterを知りました。 Python/Rubyで学んだのですが、Elixirでもあるか探してみたらありました。(なかったら作ってみようとしてた) 使い方は簡単で、Readmeに書いている通りにするだけです。 Jupyter https://jupyter-notebook.readthedocs.org/en/stable/index.html https://github.com/jupyter IElixir https://github.com/pprzetacznik/IElixir IErlang https://github.com/robbielynch/ierlang そのほか、利用可能なKernelは以下 https://github.com/ipython/ipython/wiki/IPython%20kernels%20for%20other%20languages こんな感じで起動できます。 ElixirというかErlang自体、こういう数値計算は得意としない領域なのですが、Elixir/Erlangをブラウザ越しに試す、という環境ではかなり使い勝手の良いものです。 🙂 追記: nbviewerを使えば、GitHub上でコードを簡単に共有もできてとても便利に使えます 🙂 (ただ、Elixir/Erlangは未対応です) http://nbviewer.ipython.org/More