Issue #14267 has been updated by jeremyevans0 (Jeremy Evans).
Backport deleted (2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN)
ruby -v deleted (ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-darwin15])
Tracker changed from Bug to Feature
I don't think this is a bug, just a detail of the implementation that changed when the optimization was applied. The Proc objects created are distinct. As Proc#== and #eql? are not defined, Object#== and #eql? are used, and as the objects are distinct, two distinct procs will not be considered equal.
I do think adding Proc#== and Proc#eql? makes sense, so I added a pull request for it: https://github.com/ruby/ruby/pull/3174
----------------------------------------
Feature #14267: Lazy proc allocation introduced in #14045 creates regression
https://bugs.ruby-lang.org/issues/14267#change-85937
* 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>