Can I use .include?() in a case statement? Ruby
Asked Answered
Y

3

14

I have started to learn Ruby. I have a small project to build a game and tried to create a function that receives user input and handles it accordingly.

def Game.listener
  print "> "

  while listen = $stdin.gets.chomp.downcase

    case listen
    when (listen.include?("navigate"))
      puts "Navigate to #{listen}"
      break
    when ($player_items.include?(listen))
      Items.use(listen)
      break
    end

    puts "Not a option"
    print "> "
  end
end

However, the case statement is unable to detect I have typed navigate. Is there a way to fix this or if I'm totally off can someone point me in the right direction?

I have found this way to solve my problem, is it a safe and reliable way?

  while listen = $stdin.gets.chomp
      case listen.include?(listen)
      when listen.include?("navigate")
        puts "Navigate to #{listen}"
      when listen.include?("test")
        puts "test"
      when $player_items.include?(listen)
        puts "Using the #{$player_items[listen]}"
        break
      else
        puts "Not a option"
      end
      print "> "
   end
Yarkand answered 29/11, 2016 at 14:43 Comment(9)
Use regex with either []-notation, scan or match.Koine
@sagarpandya82 Thank you. Can you provide me with an example of how this works? I'm new to this areaYarkand
(listen.include?("navigate")) equals true or false, so the line following is executed if listen equals that logical value. That's not what you want. You need to change case listen to case.Joelynn
Exactly what I needed. Thanks for the explanation. If you put this as answer I can mark your answer as solution.Yarkand
Glad to help. I can't post an answer right now, but someone else will. Please don't be in a rush to accept any answer as you don't want to discourage others.Joelynn
I see @spickermann posted a good answer. (The posting times show he undoubtedly did not see my comment before he posted.)Joelynn
r = /\bhello\b/; listen[r]; listen.scan(r); listen.match(r). See square-bracket notation, String#scan and String#match for more info.Koine
listen is a String, listen.include?('navigate') is a boolean. A boolean will never be equal to nor will it match a String, therefore that branch can never execute … and the same for all the other branches.Triclinic
There's some additional information in https://mcmap.net/q/40545/-how-to-write-a-switch-statement-in-ruby that may be helpful to folks here.Irredentist
V
20

If you want to use a case instead of an if-elsif block, then you can write it like this (note the blank space after the case):

while listen = $stdin.gets.chomp
  case
  when listen.include?('navigate')
    puts "Navigate to #{listen}"

  when listen.include?('test')
    puts 'test'
  
  when $player_items.include?(listen)
    puts "Using the #{$player_items[listen]}"
    break

  else
    puts "Not an option"
  end

  print "> "
end
Virgina answered 29/11, 2016 at 15:18 Comment(0)
B
0

In your case use a if elsif

if listen.include?("navigate")
  # ...
elsif $player_items.include?(listen)
  # ...
end
Brina answered 29/11, 2016 at 14:46 Comment(1)
Wow quick response! That'll work, thank you. I was wondering though if there was a cleaner way since the game will "listen" to a lot more inputs in the future. Hence I chose to use caseYarkand
S
0

You can also use :

AAA_TYPES = ["A", "B", "C"]
BBB_TYPES = ["D", "E", "F"]

case type_code
when *AAA_TYPES
  #.....
when *BBB_TYPES
  #.....
else
  #.....
end
Splasher answered 9/1 at 15:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.