Handling Ruby Exceptions: Fixing Initialize Errors Example

I’m working on a ruby program where I need to prompt the user to enter both their first and last names in a single line. The program should throw an exception if the user only provides one name (either first or last). I’m running into an error at the end of my code, code as shown below.

Error Code:

 class MyNewException < Exception
attr_accessor :first, :last
def initialize (first, last)
@first = first
@last = last
end
end

print "Enter your first and last name:"

begin

first, last = gets.chomp.split

print "Hello," + first + " " + last + "!"

if last.size == 0
raise MyNewException, "Sorry, I didn't catch that! Try again:"
end
rescue MyNewException
puts "Sorry, I didn't catch that. Try again:"
retry
end

Keep getting an error in above code:

testing.rb:15:in `+': no implicit conversion of nil into String (TypeError)

The error occurs because the split method may return fewer than two elements if the user enters only one name. In this case, last will be nil, and when attempting to concatenate it with a string, Ruby raises a TypeError.

Here’s an explanation and a corrected version of the code:

Problem in the Original Code:

  • When the user inputs only one name, split assigns that name to first, and last becomes nil.
  • Attempting to concatenate nil with a string using + (in the line print "Hello," + first + " " + last + "!") causes the TypeError because nil cannot be implicitly converted to a string.

Corrected Code:

To fix this, we can verify if last is nil or empty before attempting to concatenate. Here’s the corrected version:

codeclass MyNewException < Exception
attr_accessor :first, :last
def initialize(first, last)
@first = first
@last = last
end
end

print "Enter your first and last name:"

begin
first, last = gets.chomp.split

# Check if last name is missing
if last.nil? || last.empty?
raise MyNewException.new(first, last), "Sorry, I didn't catch that! Try again:"
end

print "Hello, " + first + " " + last + "!"
rescue MyNewException => e
puts e.message
retry
end

Explanation of the Changes:

  1. Check for nil or Empty last: Before concatenating first and last, we check if last is nil or an empty string. If it is, we raise the MyNewException.
  2. Using MyNewException.new(first, last): We create an instance of MyNewException with first and last, ensuring the exception handling works as intended.
  3. Improved Error Message Display: When the exception is raised, e.message provides a clearer error message to prompt the user to retry.

With these changes, the code will handle the situation where only one name is entered, avoiding the TypeError.

Related blog posts