I am beginner in ruby language so, I tried to print this line
a = 2
z = "A"
print a * z
then I get this Error
Traceback (most recent call last):
20: from /usr/local/bin/irb:23:in `<main>'
19: from /usr/local/bin/irb:23:in `load'
18: from /var/lib/gems/2.7.0/gems/irb-1.3.7/exe/irb:11:in `<top (required)>'
1: from (irb):24:in `<main>'
(irb):24:in `*': String can't be coerced into Integer (TypeError)
But when I tried to using this code it's work in the right way and I didn't receive any error
puts z * 2
or
puts "A" * 2
or
z*a
HERE I DON'T USE PRINT, PUTS, P
so why I got the error in the beginning example and what is the Mechanism of Action of two code
The short answer: the order matters.
a * z
is basically equivalent to a.send(:*, z)
meaning you call a *
method on a
and pass z
as its argument,
and
z * a
is z.send(:*, a)
meaning calling *
method on z
object, and passing a
as an argument.
So... if you check the docs:
https://ruby-doc.org/core-3.0.2/String.html#method-i-2A
string's *
method expects int as it's argument, and
https://ruby-doc.org/core-2.5.0/Integer.html#method-i-2A
int's *
expects a numeric (int or float) to be passed as an argument.
Or, to put it differently, * (and +,- etc.) are not operators in Ruby (like they are operators in C or other langs) but are just what is called a syntactic sugar to make your life easier, but are in fact methods on the objects.
I changed the variable names to represent their types and simplify the explanation.
string = 'A' # from z = 'A'
integer = 2 # from a = 2
Next, let's identify what does the *
operator (method) does:
# string * integer -> new_string
# returns a new `String` containing `integer` copies of the receiver.
puts string * integer # repeat A twice
# "AA"
In the above, a string responds to *
and accepts an integer argument.
The other examples perform a multiplication:
# integer * integer -> numeric_result
# performs multiplication
puts integer * 2 # multiply 2 by 2
# 4
so why I got the error in the beginning example
Because string's *
operator/method requires an integer argument.
HERE I DON'T USE PRINT, PUTS, P
print
, puts
and p
simply output the result of the operation or a statement, they just behave differently. You can still see the result without using them (in IRB or Rails console)
'A' * 2
# => 'AA'
2 * 2
# => 4