Elixirのatom型は、固定された定数を表します。アトムの値は、それ自身の名前そのものです。これにより、型安全な方法でデータを扱えます。アトムは次のように定義できます。
# All atoms are preceded with a ':' then follow with alphanumeric snake-cased characters
variable = :an_atom
_アトム_は、内部的にはルックアップテーブル内の整数として表現されており、この値は自動的に設定されます。この内部の値を変更することはできません。
条件によって分岐するコードを書きたいことがよくあります。Elixirではこれを行う方法がたくさんありますが、もっとも簡単な方法の1つはcond/1を使うことです。
もっとも単純な形では、condは、1つ以上の分岐のうち、最初にtrueと評価されたパスをたどります。
cond do
x > 10 -> :this_might_be_the_way
y < 7 -> :or_that_might_be_the_way
true -> :this_is_the_default_way
end
どのパスもtrueと評価されなかった場合、ランタイムがエラーを発生させます。
いくつかのアプリケーションで構成されるシステムを運用していて、それらが大量のログを出力しているとします。それらのログを集約し、重要度に応じてラベルを付ける小さなプログラムを書きたいとします。システム内のすべてのアプリケーションは同じログコードを使いますが、一部のレガシーアプリケーションはすべてのコードに対応しているわけではありません。
| ログコード | ログのラベル | レガシーアプリでの対応 |
|---|---|---|
| 0 | trace | いいえ |
| 1 | debug | はい |
| 2 | info | はい |
| 3 | warning | はい |
| 4 | error | はい |
| 5 | fatal | いいえ |
| その他 / 未対応 | unknown | - |
LogLevel.to_label/2関数を実装しましょう。この関数は、整数のコードと、そのログがレガシーアプリからのものかどうかを示す真偽値のフラグを受け取り、ログの行のラベルをアトムとして返します。
表にないログコードは、_unknown_というラベルを返すようにします。表でレガシーアプリでは未対応とされているログコードも、そのログがレガシーアプリから来たものであれば、_unknown_というラベルを返します。
LogLevel.to_label(0, false)
# => :trace
LogLevel.to_label(0, true)
# => :unknown
予期しないことが起きたときには、誰かに通知する必要があります。
アラートを誰に送るべきかを判定するために、LogLevel.alert_recipient/2関数を実装しましょう。この関数は、整数のコードと、そのログがレガシーアプリからのものかどうかを示す真偽値のフラグを受け取り、通知先の名前をアトムとして返します。
前のタスクのLogLevel.to_label/2関数を使います。ログのラベルが_error_または_fatal_なら、_ops_チームにアラートを送ります。レガシーシステムから_unknown_というラベルのログを受け取った場合は、_dev1_チームにアラートを送ります。それ以外の_unknown_ラベルは_dev2_チームに送ります。そのほかのログのラベルはすべて、_false_を返して無視して問題ありません。
LogLevel.alert_recipient(-1, true)
# => :dev1
LogLevel.alert_recipient(0, false)
# => false