Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Ruby, why does`it` get set to false after a rescue?

Tags:

ruby

In Ruby 3.4 why does Ruby's it default block parameter get set to false after a rescue in a block?

42.tap do
  puts "it is #{it}"
  raise "uh oh"
rescue
  puts "it is now #{it}"
end

prints:

it is 42
it is now false

If you use _1 instead of it it works as expected.

like image 382
nicholaides Avatar asked Sep 07 '25 15:09

nicholaides


1 Answers

According to Bug #21313 – it in rescue/ensure on prism, this is a bug that is specific to the YARV Ruby Implementation, and even more precisely, the bug only occurs when using the new Prism parser:

ruby bug21313.rb
# ruby 3.4.5 (2025-07-16 revision 20cda200d3) +PRISM [arm64-darwin24]
# false

ruby --parser=parse.y bug21313.rb
# ruby 3.4.5 (2025-07-16 revision 20cda200d3) [arm64-darwin24]
# 0

jruby bug21313.rb
# jruby 10.0.1.0 (3.4.2) 2025-07-17 0f10d1dfdf OpenJDK 64-Bit Server VM 24.0.2 on 24.0.2 +indy +jit [arm64-darwin]
# 0

As you can see, with JRuby, the result is correct. Also, with YARV, the result is correct if you turn off the Prism parser.

TruffleRuby, MRuby, PicoRuby, and Opal do not support it.

The bug was fixed in Pull Request 13360 [Bug #21313] Handle it in rescue and ensure blocks. It looks like the bug fix was not backported to YARV 3.4, so you will have to wait until YARV 3.5 if you need YARV and Prism, or use YARV without Prism or JRuby in the meantime.

For the record, this is the test case (cribbed from the bug report):

puts RUBY_DESCRIPTION

1.times do
  raise
rescue
  p it
end
like image 150
Jörg W Mittag Avatar answered Sep 10 '25 07:09

Jörg W Mittag