2

So I have the following code:

print "input please: "
user_input = gets.chomp.downcase!

if user_input.include? "s"
  user_input.gsub!(/s/, "th")
else 
  puts "There is no S in your input"
end

which throws me an error regarding the include method

when I run this it works:

print "input please "
user_input = gets.chomp
user_input.downcase!

if user_input.include? "s"
  user_input.gsub!(/s/, "th")
else 
  puts "There is no S in your input"
end

is it not possible to call multiple methods on a variable?

5
  • What error do you get? Commented Feb 14, 2021 at 21:55
  • this is what I get : main.rb:4:in <main>': undefined method include?' for nil:NilClass (NoMethodError) Commented Feb 14, 2021 at 21:57
  • You might be interested in stackoverflow.com/a/14948228/2166798 for a more generic view of what's happening. Commented Feb 14, 2021 at 22:36
  • As an aside, your code could be replaced with the following. obj = gets.chomp.downcase.gsub!(/s/, "th"); puts 'There is no S in your input' if obj.nil?; obj. That's because gsub! returns nil if there is no match. (I'm not advocating this.) Commented Feb 14, 2021 at 22:40
  • Calling multiple methods on the same object is called method cascading – a feature that Ruby unfortunately doesn't have. You can of course use method chaining, but you have to take each method's return value into account. For example, gets can already return nil. (try hitting ctrl-d when prompted for input) Commented Feb 15, 2021 at 9:24

1 Answer 1

3

It is permissible (and recommended!) to chain methods in Ruby as you have done with gets.chomp.downcase!. However, using downcase! as opposed to the form downcase is causing an unexpected behavior in your code. According to the docs, the downcase! form

Downcases the contents of str, returning nil if no changes were made.

So if your input does not contain any upper case letters, downcase! returns nil and that causes an error down the line when you call .include? on it. Try it out with input like this string:

input please: No letter in here!
# prints
There is no S in your input

But the same called without the upper N errors:

input please: no letter in here!
Traceback (most recent call last):
test.rb:4:in `<main>': undefined method `include?' for nil:NilClass (NoMethodError)

If you supply input that does contain upper case characters, you'll get no error with your original code. The fix for this is to use the non-! form:

# Don't use the ! form of downcase
user_input = gets.chomp.downcase

Because the downcase! form is intended to modify a variable rather than modify a transient string such as the string returned by .chomp.

I suspect you intended to puts user_input there also, following your .gsub! call. Your string replacement s to th does work correctly if you add that in.

Sign up to request clarification or add additional context in comments.

1 Comment

thank you very much for your thorough explanation and solution !!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.