Issue #12402 has been updated by Noah Gibbs.


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.



----------------------------------------
Bug #12402: Inline rescue behavior inconsistent for method calls with arguments and assignment
https://bugs.ruby-lang.org/issues/12402#change-59212

* Author: Ben Klang
* Status: Open
* Priority: Normal
* Assignee: 
* ruby -v: 2.4.0
* Backport: 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN
----------------------------------------
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



-- 
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>