How to Write a Switch Statement in Ruby

How to write a switch statement in Ruby

Ruby uses the case expression instead.

case x
when 1..5
"It's between 1 and 5"
when 6
"It's 6"
when "foo", "bar"
"It's either foo or bar"
when String
"You passed a string"
else
"You gave me #{x} -- I have no idea what to do with that."
end

Ruby compares the object in the when clause with the object in the case clause using the === operator. For example, 1..5 === x, and not x === 1..5.

This allows for sophisticated when clauses as seen above. Ranges, classes and all sorts of things can be tested for rather than just equality.

Unlike switch statements in many other languages, Ruby’s case does not have fall-through, so there is no need to end each when with a break. You can also specify multiple matches in a single when clause like when "foo", "bar".

Writing a test for a case statement in Ruby

This answer will help you. Nonetheless I'll post one way of applying it to your situation. As suggested by @phortx when initializing a game, override the default user-input with the relevant string. Then by using assert_output we can do something like:

#test_game.rb
require './game.rb' #name and path of your game script
require 'minitest/autorun' #needed to run tests

class GameTest < MiniTest::Test

def setup
@game_i = Game.new("i") #overrides default user-input
@game_q = Game.new("q")
@game_p = Game.new("p")
end

def test_case_i
assert_output(/information\n/) {@game_i.input}
end

def test_case_q
assert_output(/quitter\n/) {@game_q.input}
end

def test_case_p
assert_output(/player play\n/) {@game_p.input}
end
end

Running the tests...

$ ruby test_game.rb
#Run options: --seed 55321

## Running:

#...

#Finished in 0.002367s, 1267.6099 runs/s, 2535.2197 assertions/s.

#3 runs, 6 assertions, 0 failures, 0 errors, 0 skips

Ruby case-when vs JavaScript switch-case

You could use an object with a ternary to set a default value like so:

const obj = {  "var1":"value1",  "var2":"value2",  "defaultVal": "value3" // default value},getVal = sVar => sVar in obj ? obj[sVar] : obj["defaultVal"];
// Use case 1:console.log(getVal("var1")); // get "var1" from the object
// Use case 2:console.log(getVal("foo")); // get "foo" from the object, doesn't exsist, so we get the default value

Ruby on Rails Switch

I assume you refer to case/when.

case a_variable # a_variable is the variable we want to compare
when 1 #compare to 1
puts "it was 1"
when 2 #compare to 2
puts "it was 2"
else
puts "it was something else"
end

or

puts case a_variable
when 1
"it was 1"
when 2
"it was 2"
else
"it was something else"
end

EDIT

Something that maybe not everyone knows about but what can be very useful is that you can use regexps in a case statement.

foo = "1Aheppsdf"

what = case foo
when /^[0-9]/
"Begins with a number"
when /^[a-zA-Z]/
"Begins with a letter"
else
"Begins with something else"
end
puts "String: #{what}"

ruby case statement with strings doesn't work (as expected)

Of course it does not match.

  • 'this is not a test'.eql?('this is not a test') evaluates to true.

  • case x when y .... end evaluates to if y === x ... end.

  • true === 'this is not a test' evaluates to false.

You either wanted case when x ... end, which evaluates to if x ... end, a slightly different syntax with a different semantics:

case
when 'this is not a test'.eql?('this is not a test')
p '1'
end

or, if you're happy with === instead of eql?, you can write

case 'this is not a test'
when 'this is not a test'
p '1'
end

How does a ruby case statement with multiple conditions work

If you want the exact substitute of if-elsif functionality, you should use empty case condition:

case
when @mails_hash.include?(mail) && @mails_hash[mail] > 0
p "true"
true
when @mails_hash.include?(mail) && @mails_hash[mail] == 0
@mails_hash[mail] =+ 1
p "false double"
false
else
p "false else"
false
end

When you put an argument in call to case, it’s used to compare against when clauses using threeequals aka case-equal:

case mail
when MailClass then ...
end

The code above actually calls MailClass.===(mail).

How to make a ruby case statement use equals to (==) rather than threequals (===)

You cannot let case to not use ===, but you can redefine === to use ==.

class Class
alias === ==
end

case datatype
when String
puts "This will print"
end
# >> This will print

Alternatively, you can create a specific class for doing that.

class MetaClass
def initialize klass
@klass = klass
end

def ===instance
instance == @klass
end
end

def meta klass
MetaClass.new(klass)
end

case datatype
when meta(String)
puts "This will print"
end
# >> This will print


Related Topics



Leave a reply



Submit