1

I am new to Ruby. My past is in Java. I am trying to use a switch case, apparently known as a case expression in Ruby. I want to accept user input, check that input to see if it includes certain characters, and then substitute those characters with other characters. When I try to run this simple program I get many syntax errors but I am not sure why. Could someone please explain to me if I am using this statement wrong and if I can even use case expression in this situation? Thank you.

    empty_string = true

    while empty_string do
    print "Pleathe enter a thtring: " 
    user_input = gets.chomp
    user_input.downcase!

      case
        when user_input.include? ("s")
            user_input.gsub!(/s/, "th")
        when user_input.include? ("ch")
            user_input.gsub!(/ch/, "th")
        when user_input == ""
            puts "You typed noting! You get nothing sir!"
        when user_input != ""
            empty_string = false
        else
            puts "There are no 's's in your string."
        end

    end

    puts "Zai jian, #{user_input}"

Below are the errors correlating by line and syntax error

rb.rb:9: syntax error, unexpected ( arg, expecting keyword_then or ',' or ';' or '\n' when user_input.include? ("s")

rb.rb:11: syntax error, unexpected keyword_when, expecting keyword_end when user_input.include? ("ch") ^

rb.rb:13: syntax error, unexpected keyword_when, expecting keyword_end when user_input == "" ^

rb.rb:15: syntax error, unexpected keyword_when, expecting keyword_end when user_input != "" ^ rb.rb:17: syntax error, unexpected keyword_else, expecting keyword_end

rb.rb:21: syntax error, unexpected keyword_end, expecting end-of-input

BELOW IS THE FIXED CODE THANKS TO @Phlip

empty_string = true

while empty_string do
print "Pleathe enter a thtring: " 
user_input = gets.chomp
user_input.downcase!

  case
    when user_input.include?("s")
        user_input.gsub!(/s/, "th")
        empty_string = false
    when user_input.include?("ch")
        user_input.gsub!(/ch/, "th")
        empty_string = false
    when user_input == ""
        puts "You typed noting! You get nothing sir!"
        empty_string = true
    else
        puts "There are no 's's in your string."
    end

end

puts "Zai jian, #{user_input}"

The issue was the spaces I had after .include?, @Phlip told me Ruby is space sensitive. I removed the white space and it worked. I ran into an issue with the boolean after and fixed that as well. It works as intended now.

Blank Reaver
  • 225
  • 3
  • 5
  • 17
  • 2
    `case user_input` should be just `case`, because each `when` has a complete boolean expression in it. – Phlip Apr 19 '18 at 18:25
  • If that doesn't fix your syntax error, edit your post and add your error lines. – Phlip Apr 19 '18 at 18:26
  • 1
    In addition to @Phlip's `case` suggestion, try adding parentheses around the `#include?` arguments (e.g. `user_input.include?("s")`). – Zoran Apr 19 '18 at 18:30
  • if a `when` clause evaluates to `true`, then no other `when` clauses are evaluated. – steenslag Apr 19 '18 at 19:01
  • @steenslag does it not matter that it is in the while loop? – Blank Reaver Apr 19 '18 at 19:05
  • @Phlip I tried removing user_input but still have the same errors,@Zoran I added parentheses but still same issue, I will edit and add error lines, and also show you the example of this working with if statements. – Blank Reaver Apr 19 '18 at 19:07
  • 5
    Ruby is space-sensitive. `user_input.include? ("s")` is different from `user_input.include?("s")`, without the space. – Phlip Apr 19 '18 at 19:21
  • @Phlip Thank you! That was the issue. I then ran into another issue with my Boolean in the while loop but I was able to solve that. I will upload the working code. Thanks again. – Blank Reaver Apr 19 '18 at 19:47
  • @CarySwoveland Thank you for those recommendations. I will remove the line numbers. – Blank Reaver Apr 19 '18 at 23:33

1 Answers1

0

My understanding is that you wish to ask the user for a string until the string contains "s" or "ch". When such a string is found you wish to make one or more substitutions in the string and print out a string containing the modified string. Here is a Ruby-like way of doing that.

user_input = nil
loop do
  print "Pleathe enter a thtring: " 
  user_input = "cheater" # gets.chomp.downcase

  case user_input
  when /s/
    user_input.gsub!('s','th')
    break
  when /ch/
    user_input.gsub!('ch','th')
    break
  when ""
    puts "You typed noting! You get nothing sir!"
  else
    puts "There are no 's's in your string."
  end
end

puts "Zai jian, #{user_input}"

If the user enters an empty string, "You typed noting! You get nothing sir!" and then "Pleathe enter a thtring: " are displayed and gets awaits another entry.

If the user enters a non-empty string that contains no "s"'s or "ch"'s, "Pleathe enter a thtring: " is displayed and gets awaits another entry.

If the user enters "Chester\n" "Zai jian, chethter" is diplayed. If the user enters "Cheater\N" "Zai jian, theater" is displayed.

If you actually wish to replace all "s"'s and "ch"'s, substitute the following for the first two when statements.

when /s|ch/
  user_input.gsub!(/s|ch/,'th')
  break

If this is done and user enters "Chester" "thethter" is displayed. (The when line could instead be written when /s/, /ch/, but I don't like that as well, in part because /s|ch/ is still needed as gsub!'s first argument.)

Note that case statements use the method Regexp#===. We therefore see that /s/.===(s) #=> true. Ruby allows us to write that /s/ === 'chester' ("syntactic sugar").

user_input = <anything> must precede the loop to make its value visible after the loop.

See Kernel#loop. For other uses of this method the handling of StopIteration exceptions is very useful when working with enumerators (instances of the Enumerator class).

=== looks a lot like ==, but they should be thought of as entirely different methods.

Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100