From: "Eregon (Benoit Daloze)" Date: 2021-10-29T20:24:13+00:00 Subject: [ruby-core:105870] [Ruby master Feature#18276] `Proc#bind_call(obj)` same as `obj.instance_exec(..., &proc_obj)` Issue #18276 has been updated by Eregon (Benoit Daloze). jhawthorn (John Hawthorn) wrote in #note-2: > In Rails we use `obj.instance_exec(&proc_obj)` in a few places. One of the downsides `instance_exec` has is that it creates a singleton class for `obj`, which isn't friendly to method caches or JITs. `Proc#bind_call` would be very useful to us if it behaved similarly but did not create a singleton class. I think `instance_exec` doesn't create a singleton class, only if needed by e.g. `Object.new.instance_exec { def foo; end }` (at least on TruffleRuby, maybe it depends how eagerly the cref is computed by the Ruby implementation). I think the same applies to `Proc#bind_call` (`-> { def foo; end }.bind_call(Object.new)`). I'm not against such a method, but IMHO this alone is not solving #18243 in a reasonable way. If an object is made shareable, every object reachable from it should be frozen or shareable, and magically ignoring the Proc's `self` is conceptually ugly and I believe very confusing for many. Maybe `Ractor.make_shareable(someProc)` should return a Proc with a special receiver (e.g., Qundef), which simply can't be called via `.call` on any Ractor and can only be called via `Proc#bind_call`. Then at least that shareable Proc wouldn't refer to any unshared object (which would violate the docs and expected semantics of `Ractor.make_shareable`) ---------------------------------------- Feature #18276: `Proc#bind_call(obj)` same as `obj.instance_exec(..., &proc_obj)` https://bugs.ruby-lang.org/issues/18276#change-94408 * Author: ko1 (Koichi Sasada) * Status: Open * Priority: Normal ---------------------------------------- `Proc#bind_call(obj)` same as `obj.instance_exec(..., &proc_obj)` ```ruby proc_obj = proc{|params...| ...} obj.instance_exec(params..., &proc_obj) ``` is frequent pattern. ``` $ gem-codesearch 'instance_exec.+\&' | wc -l 9558 ``` How about to introduce new method `Proc#bind_call`? ```ruby class Proc def bind_call obj, *args obj.instance_exec(*args, &self) end end pr = ->{ p self } pr.bind_call("hello") #=> "hello" pr.bind_call(nil) #=> nil ``` It is similar to `UnboundMethod#bind_call`. ---- My motivation; I want to solve shareable Proc's issue https://bugs.ruby-lang.org/issues/18243 and one idea is to prohibit `Proc#call` for shareable Proc's, but allow `obj.instance_exec(&pr)`. To make shortcut, I want to introduce `Proc#bind_call`. `UnboundProc` is another idea, but I'm not sure it is good idea... Anyway, we found that there are many usage of `instance_exec(&proc_obj)`, so `Proc#bind_call` is useful not for Ractors. -- https://bugs.ruby-lang.org/ Unsubscribe: