From: "tenderlovemaking (Aaron Patterson) via ruby-core" Date: 2025-06-25T22:51:42+00:00 Subject: [ruby-core:122602] [Ruby Bug#21451] Ractor.make_shareable(->{}, copy: true) raises unhelpful error Issue #21451 has been updated by tenderlovemaking (Aaron Patterson). Eregon (Benoit Daloze) wrote in #note-1: > This doesn't really explain from a user POV why it can't copy the Proc though, after all `->{}.dup` works fine. > "No allocator" is an internal thing `Ractor.make_shareable` could work around, is there a more fundamental reason why it shouldn't work? > > Maybe the correct fix here is to actually support `Ractor.make_shareable(->{}, copy: true)`, as mentioned in #21039? AFAIK, procs fundamentally can't be shared because their environment is mutable. Even if we copy the proc, its environment is still mutable so I'm not sure if `make_shareable` should ever work on them. OTOH, if you send the proc to a Ractor I could see it getting copied at that boundary as only the receiving Ractor gets the proc. That said, I think I should have been more clear in this ticket description. IMO the problem isn't with Procs in particular, it's any object that can't be copied via `make_shareable`. The error message is not helpful. Here is an example that doesn't use a Proc: ```ruby obj = "".freeze begin obj.bar rescue => err end p err Ractor.make_shareable err, copy: true ``` The exception is a `TypeError` rather than something more helpful: ``` > ruby test.rb # :828:in 'Ractor.make_shareable': allocator undefined for RubyVM::InstructionSequence (TypeError) from test.rb:8:in '
' ``` I think we should just accept that `rb_obj_clone` can possibly raise an exception, and we should re-raise with a more helpful exception. The current behavior is even more unhelpful when you consider that the non-copiable object may be part of a larger object graph. Consider this code: ```ruby def make_lambda lambda { } end def make_lambda2 lambda { } end hash = { key: make_lambda } Ractor.make_shareable hash, copy: true ``` With the current version of Ruby, the exception is like this: ``` > ruby test.rb :828:in 'Ractor.make_shareable': allocator undefined for Proc (TypeError) from test.rb:11:in '
' ``` Fortunately the test program is short, but if this hash came from a distant place in the application, how would we know _which_ Proc is the problem? Currently we get this type of error when trying to make a Rails application shareable. But the only way I can find the specific lambdas causing problems is by hacking Ruby. At least with the patch I've provided, I can see from the error message more info about the troublesome object. ---------------------------------------- Bug #21451: Ractor.make_shareable(->{}, copy: true) raises unhelpful error https://bugs.ruby-lang.org/issues/21451#change-113840 * Author: tenderlovemaking (Aaron Patterson) * Status: Open * Assignee: ractor * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- ``` > ruby -e'Ractor.make_shareable(->{}, copy:true)' :828:in 'Ractor.make_shareable': allocator undefined for Proc (TypeError) from -e:1:in '
' ``` This error isn't very helpful and I think we can improve it. The exception happens when we call `rb_obj_clone` on the lambda. I've made a patch to improve the error message so it's like this: ``` > ./miniruby -e'Ractor.make_shareable(->{}, copy:true)' -e:1:in 'Ractor.make_shareable': cannot copy # (Ractor::IsolationError) from -e:1:in '
' -e:1:in 'Ractor.make_shareable': allocator undefined for Proc (TypeError) from -e:1:in '
' ``` The patch is here: https://github.com/ruby/ruby/pull/13703 -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/