Bug #17420

Updated by Eregon (Benoit Daloze) over 1 year ago

With an empty file `a.rb`: 
 $ ruby --disable-gems -e ' { puts $" }.take' 
 -e:1:in `block in <main>': can not access global variables $" from non-main Ractors (RuntimeError) 
 ``` (RuntimeError)``` 
 That is expected, given the rules for global variables. 

 ruby --disable-gems -e ' { require "./a.rb"; }.take; p $"' 
 [... , "/home/eregon/a.rb"] 
 Is it OK that the Ractor can do `require`, which does modify `$"`? 

 I think it's not, and it might lead to segfaults if e.g. the main Ractor mutates `$"` in parallel to some other Ractor doing `require`. 

 Probably `require` needs to be forbidden in non-main Ractors (it does mutate `$"`, so it's logical), or there needs to be always VM-global synchronization on any access to `$"` (otherwise, segfaults are possible). 
 The latter doesn't seem reasonable, especially when considering the user might do `$".each { ... }`. 


 Note that RubyGems' `require` does not work on non-main Ractors (pretty much expected given it depends on a lot of global state): 
 $ ruby -e ' { require "./a.rb"; }.take' 
 <internal:/home/eregon/prefix/ruby-master/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:37:in `require': can not access non-shareable objects in constant Kernel::RUBYGEMS_ACTIVATION_MONITOR by non-main ractor. (NameError) 

 This probably also has consequences for `autoload`. 
 Maybe the `zeitwerk` gem can help with the mode to resolve all autoload at once.