この記事では、毎年少しずつ変化している標準添付ライブラリ、Default gemsとBundled gemsのRuby 3.
標準添付ライブラリとDefault gems/Bundled gems、それぞれの違い
私、柴田はRubyインタプリタと同時に配布されている便利なライブラリ群
標準ライブラリ
標準ライブラリは、RipperやCoverageなど、Rubyのインタプリタの挙動に深く依存するライブラリです。標準ライブラリはgemとして配布したとしても、動かすことができるRubyのバージョンがRubyのminorバージョンと同一になってしまいます。つまり、Ruby 3.
後述するDefault gemsやBundled gemsという概念の導入前はすべての標準添付ライブラリが、Rubyのバージョンとともに更新されるという状態でした。この状態はRipperなどのようにRubyインタプリタと密結合している標準ライブラリにとってはわかりやすいですが、ライブラリにセキュリティアップデートが必要とされるような脆弱性が見つかった場合にRubyインタプリタも含めた新しいバージョンのリリースが必要となります。
また、標準ライブラリはRubyインタプリタのインストール先と同じディレクトリの下に配置され、そのディレクトリは$LOAD_
に追加されるため、RubyGemsやBundlerの環境下であってもrequire
によって呼び出すことができます。
Default gems
Default gemsは標準添付ライブラリのうち、Rubyインタプリタに依存しないライブラリgem update
やbundle update
でバージョンをアップデートすることができます。
Default gemsは標準ライブラリをgemとして配布したもののため、標準ライブラリ同様にRubyGemsやBundlerの環境下であっても、require
によって呼び出すことができます。また、セキュリティアップデートや、新機能をいち早く使いたい場合などにRubyGemsのgem
メソッドやBundlerのGemfile
を用いることで任意のバージョンを呼び出すことも可能です。
Bundled gems
Bundled gemsはDefault gemsの中から、Rubyコミッタによる開発を卒業して、Rubyコミッタ以外の開発者がリリースまで含めたメンテナンスを行うようになったgemです。中には最初からgemとしてリリースされたもののうち、Rubyのリリースバージョンとともに動くことが保証された上で一緒にインストールされたほうが良いと判断されたものが、Bundled gemsとして含まれることもあります。
Bundled gemsはRailsなど通常のgemに以下の項目を与えたものになります。
- Rubyインタプリタと共にインストールされる。Rubyインタプリタがサポートしているプラットフォームでビルド・
インストールできることが保証されている - Rubyインタプリタの開発と共にテストが行われている。Rubyのリリースバージョンで動くことが保証されている
gemのインストールや動作確認は時にして期待通りにならないことが多く、上記の2項目だけでも利用者にとっては大きいメリットと思います。また、Bundled gemsは標準ライブラリやDefault gemsとは異なり、通常のgemのインストールと同様に扱われるため、ユーザーが任意にアンインストールすることもできます。そして、Bundlerの環境下で利用する場合はGemfile
に明示的に記述する必要があります。
注目すべきRuby 3.3での標準添付ライブラリのアップデート
Ruby 3.
readline-extが削除された
Ruby 3.readline-ext
と呼ばれるlibreadline
の機能を扱えるようにするラッパーライブラリと、Rubyで書かれたlibreadline
の互換ライブラリであるreline
、そしてreadline-ext
とreline
を切り替えるためのライブラリであるreadline
の3つがDefault gemsとして添付されていました。
Ruby 3.reline
が実用上問題ないレベルでreadline-ext
の代わりとして利用できると判断し、readline-ext
が削除されました。この変更により、require "readline"
を実行するとreline
が呼び出されるようになります。従来のreadline-ext
を利用したい場合はgem install readline-ext
でインストールするか、BundlerのGemfile
にgem "readline-ext"
と記述することで利用できます。
実用上問題ないレベルとはいえ、まだまだreline
にはreadline-ext
とは異なる挙動が残っています。発見した場合はrelineのリポジトリのIssueに報告していただけると幸いです。
raccがBundled gemsになった
raccはRubyとCで書かれたLALR(1)パーサジェネレータです。Ruby 3.
この変更により、Ruby 3.Gemfile
にgem "racc"
と明示的に記述する必要があります。
Bundled gemsの警告機能の追加
私はRubyのリポジトリのみに存在していたライブラリについて、Default gemsに変更し、さらにBundled gemsに変更するという活動を通して、新しいメンテナを見つけてRubyのライブラリの持続的な開発が行えるようになることを目指しています。しかし、前の節で紹介したように、Default gemsからBundled gemsにすることで利用者からみると対象のライブラリを Gemfile
に追加するという作業を必要とします。
そこで、Ruby 3.
Bundled gemsの利用時に警告が出るケース
警告の対象となるライブラリはRuby 3.
- abbrev
- base64
- bigdecimal
- csv
- drb
- getoptlong
- mutex_
m - nkf
- observer
- resolv-replace
- rinda
- syslog
以降は具体的な挙動について解説を行います。
この警告機能はBundlerの環境下でのみ有効となります。そのため、テストコードではGemfileではなく、bundler/
を用いていますが、gemfile
ブロックの中はGemfile
に記載されているものと読み替えてください。
require "bundler/inline"
gemfile do
source "https://rubygems.org"
end
require "mutex_m"
require "rss"
上記のコードをRuby 3.
$ ruby test_warn_bundled_gems.rb test_warn_bundled_gems.rb:7: warning: mutex_m was loaded from the standard library, but will no longer be part of the default gems since Ruby 3.4.0. Add mutex_m to your Gemfile or gemspec. test_warn_bundled_gems.rb:8: warning: rss was loaded from the standard library, but is not part of the default gems since Ruby 3.0.0. Add rss to your Gemfile or gemspec. /Users/hsbt/.local/share/rbenv/versions/3.3.0-dev/lib/ruby/3.3.0/bundled_gems.rb:74:in `require': cannot load such file -- rss (LoadError)
この警告はmutex_
ライブラリはRuby 3.rss
ライブラリはRuby 3.Gemfile
に明示的に記述する必要があります。
require "bundler/inline"
gemfile do
source "https://rubygems.org"
gem "mutex_m"
gem "rss"
end
require "mutex_m"
require "rss"
最初のコードのgemfile
ブロックにgem "mutex_
とgem "rss"
を追加することで、警告が出なくなります。
$ ruby test_warn_bundled_gems.rb # 何も出力されない
ライブラリ開発者向けの警告
また、この警告は、ライブラリの中で使われている場合にも出力されます。たとえばRails 7.
require "bundler/inline"
gemfile do
source "https://rubygems.org"
gem "activesupport", "7.0.7.2"
end
require "active_support/all"
実行結果は以下のとおりです。
$ ruby test_warn_dependency.rb /Users/hsbt/.local/share/gem/gems/activesupport-7.0.7.2/lib/active_support/core_ext/big_decimal/conversions.rb:3: warning: bigdecimal was loaded from the standard library, but will no longer be part of the default gems since Ruby 3.4.0. Add bigdecimal to your Gemfile or gemspec. Also contact author of activesupport-7.0.7.2 to add bigdecimal into its gemspec. /Users/hsbt/.local/share/gem/gems/activesupport-7.0.7.2/lib/active_support/notifications/fanout.rb:3: warning: mutex_m was loaded from the standard library, but will no longer be part of the default gems since Ruby 3.4.0. Add mutex_m to your Gemfile or gemspec. Also contact author of activesupport-7.0.7.2 to add mutex_m into its gemspec.
最初の例と同様に、bigdecimalとmutex_
自分のコードでbigdecimalを使ってる場合には、Gemfile
などに追加するだけで解決できますが、根本的な解決としてはactivesupportが依存関係としてbigdecimalを追加する必要があります。なお、2024年1月29日時点ではRails 7.7.
ブランチでは対応済みなので、7.
まとめとRuby 3.4に向けて
この記事では、Ruby 3.
Ruby 3.