why I get error when I try to print [string * Intger] in ruby?

Viewed 66

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

2 Answers

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
Related