cwhitt91
cwhitt91

Reputation: 87

Unsure about the .include method - Need help debugging

I am creating a simple Magic-8 Ball program in Ruby. I want to make sure the user asks a question, so I've used the .include method in my conditional statements. I swore I was using it correctly, but I am getting errors when I run the program in the terminal.

I've tried using the .include method in different ways according to what I found on google, but nothing seems to be working.

    puts "Please ask the Magic 8 Ball a YES/NO question:"
    question = gets.chomp

    puts "Please enter your name:"
    name = gets.chomp

    magic_8 = rand(6)

    if question.include? "?" && magic_8 == 0
      puts "\nIt is certain, #{name}."
    elsif question.include? "?" && magic_8 == 1
      puts "\nI'm not so sure, #{name}."
    elsif question.include? "?" && magic_8 == 2
      puts "\nI'll have to get back to you on that, #{name}."
    elsif question.include? "?" && magic_8 == 3
      puts "\nIt's not likely, #{name}."
    elsif question.include? "?" && magic_8 == 4
      puts "\nAbsolutely, #{name}!"
    elsif question.include? "?" && magic_8 == 5
      puts "\nDefinitely not, #{name}."
    else
      puts "Please enter a valid YES/NO question, #{name}."
    end

I am expecting the program to output the conditional statements randomly as long as the user enters a question containing a "?".

Upvotes: 0

Views: 60

Answers (2)

Schwern
Schwern

Reputation: 164679

/Users/schwern/tmp/test.rb:9:in `include?': no implicit conversion of false into String (TypeError)
    from /Users/schwern/tmp/test.rb:9:in `<main>'

The problem is precedence. You can usually get away with not putting parenthesis around method arguments, but not this time.

question.include? "?" && magic_8 == 0

You're expecting this:

question.include?("?") && magic_8 == 0

But because && has a very high precedence, Ruby is interpreting this.

question.include?("?" && magic_8 == 0)

"?" && magic_8 == 0 is false so that's question.include?(false) which doesn't make sense.

So you need to be explicit about your parens. question.include?("?") && magic_8 == 0.

We can also avoid the problem entirely by noticing that you're checking question.include?("?") over and over again. This can be pulled into its own if/else block.

if question.include?("?")
  case magic_8
  when 0
    puts "\nIt is certain, #{name}."
  when 1
    puts "\nI'm not so sure, #{name}."
  when 2
    puts "\nI'll have to get back to you on that, #{name}."
  when 3
    puts "\nIt's not likely, #{name}."
  when 4
    puts "\nAbsolutely, #{name}!"
  when 5
    puts "\nDefinitely not, #{name}."
  end
else
  puts "Please enter a valid YES/NO question, #{name}."
end

We only need to check if they've asked the question once. Then inside that if we can use case/when, which is like a more convenient if/elsif, to check the 8 ball.

Upvotes: 1

anothermh
anothermh

Reputation: 10526

Use parentheses for arguments to method calls. You're confusing the interpreter without them.

if question.include?("?") && magic_8 == 0
  puts "\nIt is certain, #{name}."
elsif question.include?("?") && magic_8 == 1
  puts "\nI'm not so sure, #{name}."
elsif question.include?("?") && magic_8 == 2
  puts "\nI'll have to get back to you on that, #{name}."
elsif question.include?("?") && magic_8 == 3
  puts "\nIt's not likely, #{name}."
elsif question.include?("?") && magic_8 == 4
  puts "\nAbsolutely, #{name}!"
elsif question.include?("?") && magic_8 == 5
  puts "\nDefinitely not, #{name}."
else
  puts "Please enter a valid YES/NO question, #{name}."
end

More here.

Upvotes: 0

Related Questions