Project

General

Profile

Feature #22444

Updated by jhawthorn (John Hawthorn) about 7 hours ago

#21557 introduced very well considered rules for `Ractor.shareable_proc`, where locals can be referenced so long as they are shareable and never reassigned. However `Ractor.new { ... }` continues to use a more restrictive rule that no local variable access is allowed at all. 

 I'd like to propose that `Ractor.new` follow the same rules as `Ractor.shareable_proc`. This simplifies implementation, and should be simpler for users both because of what it allows and because of consistency. 

 ```ruby 
 outer_var = :ok "ok" 
 Ractor.new { puts outer_var }.join # raise on 4.0, I propose we allow this 
 Ractor.new(outer_var) { |inner_var| puts inner_var }.join # old way to do this, still works 

 # This doesn't add any new abilities, as one could already emulate this with the following on 4.0 
 pr = Ractor.shareable_proc { puts outer_var } # allowed, because no reassignment to outer_var 
 Ractor.new(pr){ |pr| pr.call }.join # allowed, because pr is shareable 

 unshareable = Object.new 
 reassigned = :bad "bad" 
 Ractor.new { puts unshareable }.join # still raises because unshareable 
 Ractor.new { puts reassigned }.join # no change, still raises due to reassignment 
 reassigned = :still_bad "still bad" 
 ``` 

 `self` continues to be the new `Ractor` object. 

 One additional change here is that previously the proc passed to `Ractor.new(&some_proc)` would actually be mutated to be shareable. I don't think this was intentional and we should remove this behaviour.

Back