Question

The rescue which could assigns a variable to reference the error object has this syntax (=>)

rescue => e

If rescue is the one of the general method call, what's the meaning of =>. Could I use the same syntax on other method call?

my_method arg1, arg2 => my_obj
Was it helpful?

Solution

While raise is indeed a method, rescue is not. It is a keyword and defined on parse.y:10467. As such, the syntax you have is special to rescue (since => e isn't any sort of method argument), and not valid for methods themselves (at least not with the same meaning). How/where the rescue => e syntax itself is defined in the parser I'm not entirely sure.

OTHER TIPS

As some football coach/philosopher-king might say, it is what it is. Here's Ruby's parse.y. Of particular interest is this part:

opt_rescue      : keyword_rescue exc_list exc_var then
                  compstmt
                  opt_rescue
                    ...
                | none
                ;

exc_list        : arg_value
                    ...
                | mrhs
                    ...
                | none
                ;

exc_var         : tASSOC lhs
                    ...
                | none
                ;

Explanation
exc_list basically allows nothing, an exception type, or a (splatted) series of exceptions like rescue ZeroDivisionError, LoadError

exc_var can be nothing or => some_variable

opt_rescue can therefore be rescue by itself or plus either or both of the above.

It's only listed here as special syntax for assignment for exceptions. The only other use for => is for key-value association.

Note also that arg_value and mrhs are on the left-hand side and lhs is on the right-hand side, which is as far as I can tell the only place where this occurs. Someone correct me if I'm wrong here, but there isn't any other "backwards" assignment in parse.y.

No, the syntax in the rescue is only used there. If you use the hash rocket '=>' in a function call like that, it will be interpreted as a hash, and if arg2 was not defined as a variable previously, it will be an error.

def foo(a,b)
  puts b.inspect
end

foo "bar", :baz => 5   #=> {:baz=>5}

foo "bar", baz => 5    #=> NameError: undefined local variable or method `baz'

baz = "flux"

foo "bar", baz => 5   #=> {"flux"=>5}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top