khurrem
khurrem

Reputation: 31

Numbers vs string/expressions vs values

When I type the following:

print "2+2 is equal to" +2+2

I get an error message saying I can't convert a number into a string, but when I type:

print "2+2 is equal to", 2+2

it's accepting it and displays:

2+2 is equal to4

What's the difference between the two? It's not making logical sense to me. Could someone please explain it?

Upvotes: 3

Views: 79

Answers (4)

fylooi
fylooi

Reputation: 3870

Everybody's pointed out how print works, so i thought i'd shed a bit of light on +.

These two operators look the same, right?

  1. '2'+'2'
  2. 2+2

In actual fact, there are two very different operations happening:

  1. String#+ - This concatenates the argument to the source string. Argument must be a string.
  2. Fixnum#+ - This adds the argument to the source number. Argument must be a number.

So if String#+ only works on string objects, how is it that we can print different types of objects?

Some classes are very 'string-like' and can be treated as strings in most contexts (eg. Exception before Ruby 1.9) as they implement to_str(implicit conversion).

We can also implement to_s in our own objects to allow it to return a String representation of the object (explicit conversion).

You can read more about this at http://codeloveandboards.com/blog/2014/03/18/explicit-vs-implicit-conversion-methods/

Upvotes: 1

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230316

print "2+2 is equal to" + 2 + 2

Here you're trying to add a number to a string. This operation doesn't make sense. It's like adding an apple to a cat. The addition fails, but if it were to succeed, then print would print the result.

print "2+2 is equal to", 2 + 2 

Here you're telling the print command to print this string and also result of summing these two numbers. it knows how to print strings and how to print numbers. Strings and numbers don't have to be mixed together in this case, they are handled separately. That's why this operation succeeds.

You can make the first operation work too. For this, you must be explicit that you want this number as a string, so that both addition operands are strings and can be actually added together.

print "2+2 is equal to" + (2 + 2).to_s

or

print "2+2 is equal to #{2 + 2}" # this is called string interpolation

Some languages try to be friendly and, if you're adding a number to a string, will stringify the number for you. Results can be... surprising.

Javascript:

"2 + 2 equals to " + 2 + 2 
# => "2 + 2 equals to 22"

"2 + 2 equals to " + (2 + 2) 
# => "2 + 2 equals to 4"

It's good that ruby doesn't do this kind of tricks :)

Upvotes: 3

spickermann
spickermann

Reputation: 106802

print "2+2 is equal to" + 2+2

fails because it tries to add a integer to a string before the result is send to print. An operation that does not make sense. Whereas:

print "2+2 is equal to", 2+2

is a other operation. Here you send two argument to print. A string and an integer. Internally print calls to_s on both values.

From the documentation:

print(obj, ...)nil

Prints each object in turn to $stdout. [...] Objects that aren't strings will be converted by calling their to_s method.

Another way to do this is string interpolation, that also calls to_s automatically:

print "2+2 is equal to #{2+2}"

Upvotes: 0

Yu Hao
Yu Hao

Reputation: 122383

print "2+2 is equal to" +2+2

is equivalent to:

print("2+2 is equal to" +2+2)

You are trying to add an integer 2 to a string "2+2 is equal to".


print "2+2 is equal to", 2+2

is equivalent to:

print("2+2 is equal to", 2+2)

Here print takes two arguemnts, one is a string, the other is an expression 2+2.

Upvotes: 0

Related Questions