ruby.wasmの怪現象 - @ledsun blog についてrubygemsにissueつくるかー、と思って調べていたら・・・迷宮入りしました。 現状をメモしておきます。
背景
ruby.wasm では、Ruby VM 初期化直後に次のような状態で返ることがあります。
Gemは定義されているrubygems.rbは未ロードGem.ruby_api_version/Gem.extension_api_versionは未定義
WASI向けにbundle install --standalone で生成される bundler/setup.rb を使うときに問題になります。k
ruby.wasm 側ではワークアラウンドを PR #622 で入れてあります。
Bundler に立てようと思っているIssueの概要
Bundler の standalone generator は generated setup.rb の中で:
require "rbconfig"は行うunless defined?(Gem)のときだけGem.ruby_api_version/Gem.extension_api_versionの簡易実装を定義する
そのため、今回のように
Gemは defined- しかし RubyGems API surface は未完成
という状態だと、フォールバック定義が入らず、 Gem.ruby_api_version を前提にしているソースコードが壊れます。
次のように個別にチェックすればいいのかな?とイメージしています。
def self.ruby_api_version RbConfig::CONFIG["ruby_version"] end unless respond_to?(:ruby_api_version) def self.extension_api_version if "no" == RbConfig::CONFIG["ENABLE_SHARED"] "\#{ruby_api_version}-static" else ruby_api_version end end unless respond_to?(:extension_api_version)
Bundlerの既存 Issue
Standalone bundle's setup.rb should implement Gem.try_activate to avoid breaking binding.irb · Issue #7545 · ruby/rubygems · GitHub が近いです。
standalone の setup.rb がpartial な Gem surface が問題を起こしています。
また、コメントで次のような設計案が出ています。
Gem.ruby_api_versionをRbConfig.ruby_api_versionに移せないかGem.extension_api_versionもRbConfig側に移せないかGem.*は将来的に deprecated にできないか
もし、これが実現すればアドホックにruby_api_versionを定義する必要が無くなります。
今回の問題の根本的な解決になりそうです。
bugs.ruby-lang.orgの既存議論
RbConfig.ruby_api_version の提案はありませんでした。
関連しそうな議論:
- Feature #16742: RbConfig.windows? and RbConfig.host_os - Ruby - Ruby Issue Tracking System
- Feature #6648: Provide a standard API for retrieving all command-line flags passed to Ruby - Ruby - Ruby Issue Tracking System
特に #6648 はとても長くて、議論に追いつけていません。
RbConfig.ruby_api_version を提案するなら、それなりに準備が必要そうです。
Gem.ruby_api_versionと RbConfig::CONFIG["ruby_version"] の違い
Gem.ruby_api_version は Gem.target_rbconfig["ruby_version"]を見ているようです。
これはクロスコンパイルと関係があるようですが、僕にはよくわかりません。
今のところ考えていること
とりあえず rubygems/rubygems にIssueを作るのは良さそうです。
あとは、せっかくRubyKaigiが近いので、RbConfigについての理解を深めておいて、誰かに直接相談したいところです。