Bug #12402
Inline rescue behavior inconsistent for method calls with arguments and assignment
Description
In this example l'm intentionally passing bad data to Date.parse
to trigger an exception. Depending on whether I use parenthesis in the method call, and whether I assign the result, I get different behavior for the inline rescue.
Code:
var1 = "apple"
var1 = Date.parse var1 rescue nil
var2 = "apple"
var2 = Date.parse(var2) rescue nil
def example1(bar)
Date.parse bar rescue nil
end
def example2(bar)
bar = Date.parse bar rescue nil
bar
end
def example3(bar)
bar = Date.parse(bar) rescue nil
bar
end
puts "Variable 1: #{var1.nil?}"
puts "Variable 2: #{var2.nil?}"
puts "Example method 1: #{example1("apple").nil?}"
puts "Example method 2: #{example2("apple").nil?}"
puts "Example method 3: #{example3("apple").nil?}"
I would expect all 5 outputs from the above script to return true.
Example:
Variable 1: false Variable 2: true Example method 1: true Example method 2: false Example method 3: true
Related issues
Associated revisions
parse.y: rescue modifier in rhs
- parse.y (command_asgn): rescue modifier in command assignment should be limited to rhs only. [Bug #12402]
parse.y: rescue modifier in rhs
- parse.y (command_asgn): rescue modifier in command assignment should be limited to rhs only. [Bug #12402]
parse.y: rescue modifier in rhs of op asgn
- parse.y (stmt, arg): rescue modifier in command op assignment should be limited to rhs only. [Bug #12402]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55887 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
parse.y: rescue modifier in rhs of op asgn
- parse.y (stmt, arg): rescue modifier in command op assignment should be limited to rhs only. [Bug #12402]
parse.y: rescue modifier in rhs of op asgn
- parse.y (stmt, arg): rescue modifier in command op assignment should be limited to rhs only. [Bug #12402]
History
#1
[ruby-core:76013]
Updated by noahgibbs (Noah Gibbs) almost 2 years ago
Hm. Yup, that definitely seems to bind funny, specifically during the parsing. Here's the Ripper output for "var1 = Date.parse var1 rescue nil" versus "var1 = Date.parse(var1) rescue nil":
2.3.1 :006 > pp Ripper.sexp("var1 = Date.parse var1 rescue nil") [:program, [[:rescue_mod, [:assign, [:var_field, [:@ident, "var1", [1, 0]]], [:command_call, [:var_ref, [:@const, "Date", [1, 7]]], :".", [:@ident, "parse", [1, 12]], [:args_add_block, [[:var_ref, [:@ident, "var1", [1, 18]]]], false]]], [:var_ref, [:@kw, "nil", [1, 30]]]]]]
Versus:
2.3.1 :007 > pp Ripper.sexp("var1 = Date.parse(var1) rescue nil") [:program, [[:assign, [:var_field, [:@ident, "var1", [1, 0]]], [:rescue_mod, [:method_add_arg, [:call, [:var_ref, [:@const, "Date", [1, 7]]], :".", [:@ident, "parse", [1, 12]]], [:arg_paren, [:args_add_block, [[:var_ref, [:@ident, "var1", [1, 18]]]], false]]], [:var_ref, [:@kw, "nil", [1, 31]]]]]]]
That shows the rescue surrounding the whole assignment in the first case (in case of failure, no assignment happens) and around just the Date.parse() call for the second one.
Not sure why it binds at a different level for one versus the other, but that's one more level of "what's happening here?" I think that means that the answer would be in parse.y.
#2
[ruby-core:76777]
Updated by matz (Yukihiro Matsumoto) over 1 year ago
I consider this is a bug. They should be consistent.
But I am not sure we can fix the issue soon. When in doubt, put parens.
Matz.
#3
[ruby-core:76778]
Updated by nobu (Nobuyoshi Nakada) over 1 year ago
- Assignee set to nobu (Nobuyoshi Nakada)
- Status changed from Open to Assigned
- Description updated (diff)
#4
Updated by nobu (Nobuyoshi Nakada) over 1 year ago
- Status changed from Assigned to Closed
#5
[ruby-core:77165]
Updated by whitequark (whitequark *) over 1 year ago
Will this be backported?
#6
[ruby-core:77396]
Updated by nagachika (Tomoyuki Chikanaga) over 1 year ago
- Backport changed from 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN to 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: WONTFIX
Even though it's a bug, the behavior change could break existing applications. I won't backport into ruby_2_3 branch.
#7
Updated by shyouhei (Shyouhei Urabe) over 1 year ago
- Related to Bug #13005: Inline rescue is inconsistent when rescuing NoMethodError added
parse.y: rescue modifier in rhs
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55851 b2dd03c8-39d4-4d8f-98ff-823fe69b080e