トップ «前の日記(2016/08/28 (日) ) 最新 次の日記(2016/08/30 (火) )» 編集 RSS feed

HsbtDiary


2016/08/29 (月) [長年日記]

Ruby 2.4.0 で導入予定の Integer Unification まとめ

Ruby 2.4.0 で導入が予定されている Integer Unification が与えるであろう Ruby アプリケーションへの影響をまとめておく。

率直には rb_cFixnumrb_cBignum が 2.4 からは見えなくなるので、それらを参照しているような native gem が対応していなければビルドできないためアプリケーションが動かなくなる。じゃあ、対応したバージョンに全てバージョンアップすればいいじゃん、という話なのだけど bundler が解決してくれる dependency 沼と絡み合って、単純には解決できずに 8 月現在は厳しい状態になっている。

  • json は Ruby が bundle しているバージョンですでに Integer Unification 対応がなされているので、 2.0.0 によってバックポートされた gem がリリースされている
  • https://github.com/flori/json/blob/master/CHANGES.md#2015-09-11-200
  • json-2.0.0 は同時に Ruby 2.0.0 以降を要求するようになっている
  • こちらは根が深いので後述する
  • oj は @hsbt が雑に直したコードがマージされて 2.16.0 としてリリースされている
  • https://github.com/ohler55/oj/pull/304
  • 2.16.0 以降を使えば Ruby 2.4.0 でも使えるので素朴にアップデートしましょう
  • yajl-ruby は @hsbt が雑に直したコードがマージされたが新しいバージョンがリリースされていない
  • https://github.com/brianmario/yajl-ruby/pull/165
  • リリースされない限り yajl-ruby は Ruby 2.4.0 では使うことができないので、困る人はロビー活動頑張りましょう

json については stdlib に含まれているバージョン(こちらは default gem と呼ぶ)と gem としてリリースされているバージョンがあり、どちらも対応済みではあるものの、bundler が参照する Gemfile や rubygems が依存先として参照する Gem::Dependency として json が指定されている場合は、指定された内容に沿った依存解決が行われる。

つまり、 Gemfile や gemspec などで '~> 1.8' というような指定をしている場合は Integer Unification に対応した 2.0 以降の gem を参照できないため、これもまた Ruby 2.4.0 では使うことができない。このような gem のほとんどは Ruby 1.8 の時代から存在し、json がバンドルされていない頃の名残、もしくは特に意味合いはないものの保守的に '~> 1.8' を指定しているものが多いものの、以下のいずれかの対応を行わなくては Ruby 2.4.0 以降に生き残ることはできないことが現時点で概ね確定している。

  • Ruby 1.8 対応をドロップして json の明示的な依存宣言を削除し、default gem としての json を使う
  • Ruby 1.8/1.9 をドロップして json '~> 2.0' を指定し、普通の gem の json を使う

オススメは Ruby コミッタ、つまり僕を含んだメンバーが依存関係をせっせと解決している前者を採用することなので、見かける範囲で json をわざわざ明示している gem がある場合は今すぐ消して新しいバージョンの gem をリリースしてほしい。Ruby の default gem としての json よりも新しいバージョンの json gem を使いたい時だけ指定すればよい。

さらに上記の問題を泥沼にしているのが、例えば Rails アプリケーションを作っている場合、その Rails アプリケーションが依存している全ての gem で Integer Unification 対応がなされなければ Ruby 2.4.0 を使うことができない、ということがある。例えば、多くの gem が参照している rdoc などは典型例で

https://github.com/rdoc/rdoc/pull/412

のような対応を取り込んだバージョンを 5.0 としてリリース予定なものの、他の gem が '~> 4.2' などとしていた場合には振り出しに戻って rdoc の依存バージョンをあげるか、幸いなことに rdoc は json 同様 default gem なため、依存自体を外すなどして対応をする必要がある。ということを、Rails アプリケーションが使ってる gem 隅々まで対応しなければならない。とても辛い。

今の所自分が気がつく範囲では、 Ruby コミッタがメンテナンスしていたりするものが多いので対応しつつあるものの、例えば、 Rails じゃないけど ActiveSupport 4.2 に依存しています、というアプリケーションやライブラリがあった場合、ActiveSupport 4.2 は json '~> 1.7' な依存のため、当然 Ruby 2.4 では動かない。

https://github.com/jekyll/jemoji/pull/49

上記のように ActiveSupport 5.0 では json の依存が消えているので解決されているので対応したとしても、 ActiveSupport 5.0 は Ruby 2.2.2 以降のみしかサポートしてないので、アプリケーションやライブラリの開発者が 5.0 への移行に慎重な場合は対応されるまで Ruby 2.4 では動かないことになる。とて もとても辛い。ほんとつらい。

まとめると「今すぐ手元や近所の gem から json や rdoc など default gem への明示的な dependency 指定は消してほしい」ということなので、RubyKaigi に向けて、みなさんよろしくお願いします。

合わせて読みたい: http://www.mikeperham.com/2016/02/09/kill-your-dependencies/

夏休みで北海道へ

ちょっと遅れた夏休みで北海道へ帰省。前半に室蘭、後半に札幌という予定。



北海道に帰ってきて最初にやることの、カツゲンを飽きるくらいのむというのとジンギスカンを食べるというノルマは初日でクリアしておいた。