Issue #14267 has been updated by jeremyevans0 (Jeremy Evans).


In my pull request, I propose the following definition of proc equivalence:

* The procs have the same class
* The procs either are both lambdas or both non-lambdas
* The procs either are both created from a method or both not created from a method
* The procs have the same block type (iseq, ifunc, symbol, proc)
  * If iseq, the proc blocks have the same ec and iseq
  * If ifunc, the proc blocks have the same ec and ifunc
  * If symbol, the proc blocks use the same symbol
  * If proc, the proc blocks use the same proc

I'm not sure if this definition is perfect, though it seems better than the object equivalence currently used. Someone with more knowledge of proc types should probably review and see if there are other conditions that should be met for equivalence.

----------------------------------------
Feature #14267: Lazy proc allocation introduced in #14045 creates regression
https://bugs.ruby-lang.org/issues/14267#change-85953

* Author: myronmarston (Myron Marston)
* Status: Open
* Priority: Normal
----------------------------------------
The following script consistently prints `Proc equality: true` on versions of Ruby before 2.5, but prints `Proc equality: false` on Ruby 2.5:

``` ruby
# regression.rb
def return_proc(&block)
  block
end

def return_procs(&block)
  block.inspect if ENV['INSPECT_BLOCK']

  proc_1 = return_proc(&block)
  proc_2 = return_proc(&block)

  return proc_1, proc_2
end

proc_1, proc_2 = return_procs { }

puts RUBY_VERSION
puts "Proc equality: #{proc_1 == proc_2}"
```

Here's the output on Ruby 2.4 and 2.5:

```
$ chruby 2.4
$ ruby regression.rb
2.4.2
Proc equality: true
$ chruby 2.5
$ ruby regression.rb
2.5.0
Proc equality: false
```

As the output shows, the two procs were equal on 2.4 but are no longer equal on 2.5.  I believe this is due to the lazy proc allocation introduced in #14045.  Note that if I call a method on the proc (such as `inspect`) it defeats the lazy allocation and "fixes" the regression:

```
$ chruby 2.5
$ INSPECT_BLOCK=1 ruby regression.rb
2.5.0
Proc equality: true
```

This caused a bug in RSpec, which I've [worked around for now](https://github.com/rspec/rspec-core/commit/84670489bb4943a62e783bd65f96e4b55360b141) by calling `__id__` on the proc.

Is there a way to keep the lazy proc allocation while fixing this regression?



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>