Confusion over strings and integers

I’m reading Chris P.s ‘How to program’ This was the latest concept,
Length:

"Another string method is length, which tells us the number of
characters
(including spaces) in the string:
puts ‘What is your full name?’
name = gets.chomp
puts ‘Did you know there are ’ + name.length + ’ characters’
puts 'in your name, ’ + name + ‘?’
What is your full name?
Christopher David Pine
#<TypeError: can’t convert Fixnum into String>

Uh-oh! See? There it is! It’s an easy mistake to make. Anyway, if
you didn’t know to be on the lookout for this error, you can still
figure
that the problem must have happened sometime after the line name =
gets.chomp, since I was able to type my name. See whether you can
figure it out.
The problem is with length: it gives us an integer, but we want a
string.
That’s easy enough; we’ll just throw in a .to_s (and cross our fingers"

I don’t see the problem with the computer giving us the integer version
of the number of characters? He then asks us to create a program
that will ask someone their first/middle/last names individually and
then add them up after. I would think to just ask for them using GETS
and then add up the lengths using the .to_s conversion… but surely what
I’ve learned about strings is that you cant add them together right?

Can anyone explain this?

Kind regards

Josh

The result of gets is indeed a String, but the return value from
String#length is a Fixnum.
You don’t need to use #to_s until the output.

total = a.length + b.length
Fixnum

total.to_s
String

puts 'length is ’ + total.to_s

Actually, you can add Strings together, as long as they’re all Strings.
As always with Ruby, there’s more than one way to do it…

a = ‘Joe’
b = ‘Bloggs’
c = a + b
=> ‘JoeBloggs’
c.length
=> 9

On Tue, Nov 26, 2013 at 11:15 PM, Joshua P. [email protected]
wrote:

Can anyone explain this?

It helps to know how Ruby deals with operators and mixed types. I
blogged about this long ago:
http://blog.rubybestpractices.com/posts/rklemme/019-Complete_Numeric_Class.html

Basically it was decided that there is no coercion for String and
Fixnum with + and other operators because it is not entirely clear
what the intended semantics would be: is is

  1. calculating the integer sum of the Fixnum and the integer
    represented by the String OR
  2. prepending / appending the string representation of the Fixnum to
    the String OR
  3. prepending / appending the character whose ASCII code is the Fixnum
    (as String#<< does)?

So the user is forced to make an explicit choice. And there is a more
idiomatic way to do what you did above with + operators: string
interpolation.

puts “Did you know there are #{name.length} characters”
puts “in your name, #{name}?”

Kind regards

robert

Thanks guys, I kind of get it.

Actually Roberts explanation was a little too advanced for me (I’m only
30 pages into my first, very basic, learn to program book) I’m a real
beginner here :slight_smile:

I’ll certainly use the method you explained Joel, to fixx my code, even
if I don’t fully understand it.

Thanks again to you both!

On Wed, Nov 27, 2013 at 12:03 AM, Joshua P. [email protected]
wrote:

Thanks guys, I kind of get it.

Actually Roberts explanation was a little too advanced for me (I’m only
30 pages into my first, very basic, learn to program book) I’m a real
beginner here :slight_smile:

Sorry for that. The minimal takeaway should then be: use string
interpolation as I’ve shown at the end of my posting for these kinds
of things. It’ll automatically invoke #to_s plus it’s usually quite
efficient.

Kind regards

robert

On Nov 26, 2013, at 4:15 PM, Joshua P. [email protected] wrote:

What is your full name?
string.

Kind regards

Josh


Posted via http://www.ruby-forum.com/.

Lets break this down into simpler bits:

"hello," + " world"

concatenates (appends) the strings together, producing “hello, world”

name = "Tamara"
"hello, " + name

again concatenates the strings together, producing “hello, Tamara”

name + ", your name contains " + name.length + " characters"

produces the error like in Chriss code, because it it mixing string
concatenation using + with a number produced by name.length. Robert has
explained why that breaks.

So to fix it, all those things need to be Strings. Chris is telling you
the .to_s method is what converts the number from name.length into a
String, so all of them can be concatenated together:

name + ", your name contains " + name.length.to_s + " characters"

finally gives us “Tamara, your name contains 6 characters”