Why am I getting an "Unexpected" error when using the * (asterisk) operator as a method parameter?

I am learning Ruby at the moment, and I came across this strange situation.

When I run the following code, I get the output shown below.

Work code:

def hello(a,b=1,*c,d,e,f) pa,b,c,d,e,f end hello(1,2,3,4,5) 

Working code output:

 1 2 [] 3 4 5 

However, when editing the code so that the 'e' parameter is the catch all parameter, I get the error below.

Failure Code:

 def hello(a,b=1,c,d,*e,f) pa,b,c,d,e,f end hello(1,2,3,4,5) 

Code exit error:

 a.rb:1: syntax error, unexpected * def hello(a,b=1,c,d,*e,f) ^ a.rb:1: syntax error, unexpected ')', expecting '=' a.rb:3: syntax error, unexpected keyword_end, expecting end-of-input 

I am using ruby ​​2.3.1p112 (2016-04-26 version 54768) on Ubuntu.

I am interested to know why the second piece of code does not work.

Edit:

The following code also does not work.

 def hello(a,b=1,c,d,e,*f) pa,b,c,d,e,f end hello(1,2,3,4,5) 

And I get a similar error

 a.rb:1: syntax error, unexpected * def hello(a,b=1,c,d,e,*f) ^ a.rb:3: syntax error, unexpected keyword_end, expecting end-of-input 
+5
source share
1 answer

The relevant documentation is here , and here is the question . It does not appear to cover all cases.

Here is what I could put together:

  • no more than one splat ( *args ) statement can be used.
  • You can use several default arguments ( a=1, b=2 ).
  • default arguments should be to the left of the splat operator.
  • multiple default arguments must come directly one after another.
  • If the default arguments and the splat operator are used, the default arguments must come right before the splat operator.
  • if the above rules are followed, the default arguments and the splat operator can be anywhere in the argument list.

For readability, it might be a good idea:

  • put the splat operator as the last argument
  • avoid placing default arguments in the middle

Here are valid method definitions:

 def hello(a = 1, b) ;end def hello(a, b = 2) ;end def hello(a = 1, b = 2) ;end def hello(a = 1, b = 2, c) ;end def hello(a, b = 2, c = 3) ;end def hello(a, b = 2, *c) ;end def hello(a, b = 2, *c, d) ;end def hello(a = 1, b = 2, *c, d) ;end 

For your second example, this syntax will be fine:

 def hello(a,b,c,d=1,*e,f) pa,b,c,d,e,f end 

For a more complete example with block and keyword arguments see @ JΓΆrgWMittag excellent answer .

+5
source

Source: https://habr.com/ru/post/1263640/


All Articles