While adding some whitespace to make code more readable (line up with code above it), I came across this:
class C
def x
42
end
end
m=C.new
Now this will give "wrong number of arguments":
m.x *m.x
And this will give "syntax error, unexpected tSTAR, expecting $end":
2/m.x *m.x
What exactly is happening in the parser here?
I tested with Ruby 1.9.2 and 2.1.5.
*
is used for both an operator (42 * 42
) and argument unpacking (myfun *[42, 42]
).
When you do:
m.x *m.x
2/m.x *m.x
Ruby interprets this as argument unpacking, rather than the *
operator (ie. multiplication).
In case you're not familiar with it, argument unpacking (sometimes also called "splat", or "splats") means that you can have a function like this:
def myfun arg1, arg2; end
And call it like this:
myfun(*['Hello', 'World'])
arg1
is set to Hello
, and arg2
is set to World
.
I believe the rules are to determine which to use is:
*
-> Argument unpacking*
operator, since Ruby does operator overloading).Good guidelines are:
*
when you intend the *
operator (multiplication).Ruby will actually warn you about this when you run ruby -v
:
test.rb|11 warning| `*' interpreted as argument prefix
test.rb|12 warning| `*' interpreted as argument prefix
In simple language:
When you say
m.x *m.x
It internally calls m.x(*m.x)
i.e it considers *m.x
as splat argument to m.x
.
Since, there is an x
method defined on m
which takes any argument(s), you are getting the "wrong number of arguments" error.
When you call
m.x * m.x
It considers *
as a method of x
which takes an object of type 'Fixnum' and in Ruby, the *
method that takes an argument is defined for 'Fixnum' class. So, it's the same as calling
m.x.*(m.x)
and hence it works!
I hope that helped you understand the problem, in case any clarification is required, feel free to comment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With