Ruby: no implicit conversion of fixnum into string - ruby

Trying to solve one of the problems in Chris Pine's book. Asks users to input their first and last names, then it should display the total number of characters of both.
Here's one of many solutions I've come up with:
puts "First name?"
first_name = gets.chomp
puts "Last name?"
last_name = gets.chomp
total = first_name.length.to_i + last_name.length.to_i
puts 'Did you know you have ' + total + ' characters in your name ' + first_name + last_name + '?'

Ruby is pretty strict about the difference between a String and an Integer, it won't convert for you automatically. You have to ask, but you can ask politely:
puts "Did you know you have #{total} characters in your name #{first_name} #{last_name}?"
You can also do the math this way:
puts "Did you know you have #{first_name.length + last_name.length} characters in your name?"
The #{...} interpolation only works inside "double-quoted" strings, but it does convert to a string whatever the result of that little block is. Single quoted ones avoid interpolation, which is sometimes handy.
If you do want to concatenate strings you have to convert manually:
"this" + 2.to_s

Length returns an integer (no need to convert to_i) so change your code to this:
total = first_name.length + last_name.length

Related

Ruby question: syntax error whilst using gets

I am attempting to run the following program, which will give out a simple greeting taking user input. However, whenever I run the code I get the following message:
syntax error, unexpected tSTRING_BEG, expecting do or '{' or '('
I've tried replacing the single quote marks with doubles, and I've also tried placing '()' around the variable names.
puts 'First name: '
first_name = gets.chomp
puts 'Middle name: '
middle_name = gets.chomp
puts 'Surname: '
surname = gets.chomp
puts "Greets to you," + first_name + middle_name + surname "! Welcome to Valhalla!"
#eux already gave a correct answer to the syntax error in your example.
I just want to show another way to generate the expected output. It's a common Ruby idiom to use string interpolation instead of string concatenation. With string interpolation, you can generate your output like this
puts "Greets to you, #{first_name} #{middle_name} #{surname}! Welcome to Valhalla!"
String interpolation has many advantages – as described in this answer and its comments. In the context of your question the pros are:
It is shorter
It is much clearer where to put whitespace
And It is overall easier to read and understand
You missed a + before ! Welcome to Valhalla! at the last line:
puts "Greets to you," + first_name + middle_name + surname + "! Welcome to Valhalla!"

String can't be coerced into Fixnum (TypeError)

I wrote the basic codes below
puts ' Hi there , what is your favorite number ? '
number = gets.chomp
puts number + ' is beautiful '
puts 1 + number.to_i + 'is way better'
But when I run it,I get the error "String can't be coerced into Fixnum (TypeError)". How do I correct this error please?
You cannot add a String to a number. You can add a number to a String, since it is coerced to a String:
'1' + 1
# => "11"
1 + 1
# => 2
1 + '1'
# TypeError!
Since I suspect you want to show the result of adding 1 to your number, you should explicitly cast it to string:
puts (1 + number.to_i).to_s + ' is way better'
or, use string interpolation:
puts "#{1 + number.to_i} is way better"
String can't be coerced into Integer usually happens, when you try to add a string to a number. since you want to add 1 to your number and concatenate it with a string "is way better". you have to explicitly cast the result you got from adding 1 to your number to a string and concatenate it with your string "is way better".
you can update your code to this:
puts (1 + number.to_i).to_s + " " + 'is way better'
Assuming that the numbers are natural numbers:
number = gets.chomp
puts "#{number} is beautiful ", "#{number.succ} is way better"
You might find the results of entering 'xyz' as an input surprising.
This discussion for determining if your input string is a number may be helpful.

Basic Ruby gets.chomp

I'm new to programming and I'm trying to answer this basic question.
Write a program which asks for a person's favorite number. Have your program add one to the number, then suggest the result as a bigger and better favorite number.
This is what I have to far, but it won't convert to a number.
puts "What is your favorite number?"
number = gets.chomp
number = number.to_i + 1
puts "I suggest " + number + " as a bigger and better number"
Look more closely at the error you get:
What is your favorite number?
42
number.rb:4:in `+': can't convert Fixnum into String (TypeError)
from number.rb:4:in `<main>'
Line 4 is:
puts "I suggest " + number + " as a bigger and better number"
The problem is that Ruby won't implicitly convert number into a string (e.g. "foo" + 42 is not valid in Ruby). There are a couple of solutions:
Call to_s on number to convert it to a string before concatenating:
puts "I suggest " + number.to_s + " as a bigger and better number"
Use Ruby string interpolation:
puts "I suggest #{number} as a bigger and better number"
Option 2 is more idiomatic, I suggest using that.
As in many other problems in ruby there are a lot of ways to do it....without the three solutions writed above there is two more:
puts "What is your favorite number?"
number = gets.chomp.to_i
puts "I suggest %d as a bigger and better number" % [number + 1]
and one wich is almost the same:
puts "What is your favorite number?"
number = gets.chomp.to_i
num = number + 1
puts "I suggest %d as a bigger and better number" % [num]
You can do it this way:
print 'What is your favorite number? '
number = gets.chomp
puts "I suggest #{number.to_i + 1} as a bigger and better number"
There is not to much to explain about the code, but there are few things to take into account:
If you are rendering plain text use 'text' instead of "text". "In the double-quoted case, Ruby does more work. First, it looks for substitutions (sequences
that start with a backslash character) and replaces them with some binary value" - Programming ruby 1.9.3
Always try to reduce the number of lines of code.
This things are really insignificant here, but when you are coding a big program, web page etc., it really makes a difference.

'+' can't convert Fixnum into String (TypeError)

I've hit upon a 'can't convert Fixnum into String (TypeError)' error and whilst it seems simple enough I'm unsure about how to get around it. I thought my logic was sound - convert the entered string variable to an integer and then carry out the basic operation - but apparently I'm missing some key bit of information.
puts 'What is your favourite number?'
favenum = gets.chomp
better = favenum.to_i + 1
puts 'Yeah '+favenum+' is nice enough but '+better+' is bigger and better by far! Think on.'
Have tried searching for an answer but examples of the same error out there are way beyond my rudimentary ruby skills at present.
Ruby (unlike some other languages) does not cast objects to strings when they are operands in String#+ method. Either cast to string manually:
puts 'Yeah ' + favenum.to_s + ' is nice enough but ' + better.to_s + ' is bigger and better by far!'
or use string interpolation (note the double quotes):
puts "Yeah #{favenum} is nice enough but #{better} is bigger and better by far!"
Try using string interpolation, like this:
puts "Yeah #{favenum} is nice enough but #{better} is bigger and better by far! Think on."
Based on the tutorial you're following
puts 'Please enter your favourite number: '
number = gets.chomp
imp = number.to_i + 1
puts 'I\'d say '.to_s + imp.to_s + ' is a much better number.'
Produces the "correct" result at a beginner level.

Adding a number to a phrase

I can print a raw number with this code:
puts 'Please enter your favorite number'
favNumber = gets.chomp
betterNumber = favNumber.to_i
puts betterNumber + 1
but I need to set a message including the number. I changed the last two lines to this, but it's wrong.
betterNumber = favNumber.to_i + 1
puts 'Your favorite number sucks, a better number is '+ betterNumber + '!'
Help me.
betterNumber is of class Fixnum and your string is of course of class String. You can't add a String and a Fixnum, you need to cast your Fixnum into a String using to_s.
"Your favorite number sucks, a better number is " + betterNumber.to_s + "!"
Also, using interpolation calls to_s on any objects being interpolated. So this works, too (and is more common):
"Your favorite number sucks, a better number is #{betterNumber}!"
Also, in Ruby we usually use snake_case variables as opposed to camelCase variables. So I recommend using better_number
You need to convert betterNumber to a string when printing it, like this: betterNumber.to_s.

Resources