DEV Community

gumi TECH for gumi TECH Blog

Posted on

Elixir: バージョン間の互換性と非推奨

本稿は「Elixir の互換性について」をもとに加筆・補正し、文章を整えました。

非推奨の機能の警告表示

Elixirは互換性を大事にしている言語です。そのため、古い機能も比較的長く残っています。

たとえば、HashDictを使うことは、Elixir 1.4から推奨されなくなりました(deprecated)。けれど、Elixir 1.7.4でも警告は出るものの、削除されていません。

iex> HashDict.new()
warning: HashDict.new/0 is deprecated. Use maps and the Map module instead

#HashDict<[]>
Enter fullscreen mode Exit fullscreen mode

また、Elixir 1.3まであったEnum.partition/2という関数は、Elixir 1.4からひっそりとドキュメントから消されました。しかし、今でも呼び出して使えます。

iex> Enum.partition([1, 2, 3], fn(x) -> rem(x, 2) == 0 end)
warning: Enum.partition/2 is deprecated. Use Enum.split_with/2 instead

{[2], [1, 3]}
Enter fullscreen mode Exit fullscreen mode

さらに、Code.load_file/2Code.loaded_files/0およびCode.unload_files/1などの関数は、Elixir 1.7から非推奨とされてドキュメントから除かれたものの、使っても警告は出ません。

deprecatedの警告がいつから出て、それらの機能がいつまで残っているのか気になるところです。

互換性のポリシー

答えはElixir公式ドキュメント「Compatibility and Deprecations」の「Deprecations」に示されています。機能の廃止は、つぎの3つの段階を踏んで進められるということです。

  1. 機能をやわらかな非推奨(soft-deprecation)とします。CHANGELOGとドキュメントの機能リストでは非推奨とするものの、コードを効果的に動作させるため、警告は出しません。機能を使わないよう強いられることはないのです。
  2. 機能を使ったとき警告を出して、非推奨であることが告げられます(hard-deprecation)。機能が円滑に削除できるよう、必ず代替手段が示されなければなりません。そのあと少なくとも2マイナーバージョンが経過してから警告が示されます。
  3. メジャーバージョンがリリースされたとき、非推奨の機能は削除されます。つまり、現在のElixir 1.xで非推奨とされている機能は、Elixir 2.xで除かれるということです。

Elixir 1.5のHashDictにdeprecated の警告が出るのは、Elixir 1.2でMapという代替機能が追加されてsoft-deprecatedになり、2マイナーバージョンを経たElixir 1.4以降になったからです。

これに対して、Elixir 1.7で非推奨とされたCode.load_file/2Code.loaded_files/0およびCode.unload_files/1などは、代替機能としてそれぞれCode.compile_file/2Code.required_files/0そしてCode.unrequire_files/1が備わったものの、2マイナーバージョンが経過していないため、soft-deprecatedとされているのです。

これらの機能は Elixir 2.0で削除されます。逆にいえば、ドキュメントから消えたりdeprecatedの警告が出るものの、Elixir 2.0までは残っていることが保証されています。

なぜsoft-deprecationの段階があるのか

多くのユーザは、わざわざCHANGELOGを見ないでしょうし、これまで動いているモジュールのドキュメントを改めて調べることは少ないと思われます。ユーザが気づくのは deprecatedの警告が出たときです。その前に、わざわざsoft-deprecationという段階を経るのはなぜでしょうか。

おそらく、警告にしたがってただちに機能を削ったとき、古いバージョンで動かなくなってしまうことを防ぐためだと推測されます。

たとえばElixir 1.5からAtom.to_char_list/1Integer.to_char_list/1といった.*char_list.*系の関数やアトムがすべて.*charlist.*に改められています。これによって、多くのライブラリが警告を出すようになりました。だからといって、すぐに直すとElixir 1.4で動かなくなってしまうなら、もう少し先に延ばそうということになるかもしれません。

しかし、.*charlist.*周りの実装は、実はElixir 1.3から入っています。つまり、警告が出た時点ですぐ直しても、過去2マイナーバージョンで動作することが保証されているのです。それが理由だとすれば、soft-deprecationはよくできた仕組みだと考えられます。

まとめ

以上のとおり、Elixirは互換性をかなり大事にしています。Elixir 2.0までは、古いコードも動くようです。安心して計画的にアップデートを行いましょう。

Top comments (0)