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 totrue
.case x when y .... end
evaluates toif y === x ... end
.true === 'this is not a test'
evaluates tofalse
.
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
Why Is It Bad Style to 'Rescue Exception =≫ E' in Ruby
Look Up All Descendants of a Class in Ruby
What's the Difference Between Uri.Escape and Cgi.Escape
How to Specify a Local Gem in My Gemfile
Incompatible Character Encodings: Ascii-8Bit and Utf-8
Actioncontroller::Unknownformat
How to Find the Local Port a Rails Instance Is Running On
Accessing Elements of Nested Hashes in Ruby
Why Do Ruby Setters Need "Self." Qualification Within the Class
How to Avoid Nomethoderror For Missing Elements in Nested Hashes, Without Repeated Nil Checks
What Does the "===" Operator Do in Ruby
What Exactly Is the Singleton Class in Ruby
Mixing Keyword With Regular Arguments in Ruby