From: matz@... Date: 2018-07-18T06:23:44+00:00 Subject: [ruby-core:87979] [Ruby trunk Feature#14914] Add BasicObject#instance_exec_with_block Issue #14914 has been updated by matz (Yukihiro Matsumoto). Real-world use-case, please? Any problem with the following code? ``` blk = proc{|x| self * x} 1.instance_exec(42, 2) do |a, b| (self + a).instance_exec(b, &blk) end # => 86 ``` Matz. ---------------------------------------- Feature #14914: Add BasicObject#instance_exec_with_block https://bugs.ruby-lang.org/issues/14914#change-72986 * Author: jeremyevans0 (Jeremy Evans) * Status: Open * Priority: Normal * Assignee: * Target version: ---------------------------------------- Currently, you cannot use `instance_exec` with a block that requires a block argument. If you have a block that requires a block argument and you want to get the equivalent of `instance_exec`, you have to do something like: ~~~ ruby singleton_class.define_method(:temporary_method_name, &block) send(:temporary_method_name, *args, &block_arg) singleton_class.remove_method(:temporary_method_name) ~~~ That approach doesn't work for frozen objects, making it impossible to get the equivalent of `instance_exec` for a frozen object if you have a block that requires a block argument. The attached patch implements `instance_exec_with_block`, which is the same as `instance_exec`, except the last argument must be a `Proc` which is passed as the block argument instead of the regular argument to the block. ~~~ ruby 1.instance_exec_with_block(42, 2, proc{|x| self * x}) do |a, b, &blk| (self + a).instance_exec(b, &blk) end # => 86 ~~~ This method cannot be implemented in a gem because it requires changes to `vm.c` and `vm_eval.c` to implement. There wasn't a function allowing you to provide both a cref and a block argument when evaluating a block (hence the addition of `vm_yield_with_cref_and_block` in the patch). There are alternative APIs that could support this feature. One approach would be adding support for `:args` and `:block_arg` keyword arguments to `instance_eval` (if no regular arguments are given). ---Files-------------------------------- 0001-Add-BasicObject-instance_exec_with_block.patch (6.04 KB) -- https://bugs.ruby-lang.org/ Unsubscribe: