Reputation: 52308
Ruby's case statement uses ===
by default. Is there a way to make it use 'equals to' (i.e. ==
) instead?
The motivation for doing so is because I have 5 if
statements that would very nicely be replaced by a switch, but I was a little surprised to learn that
datatype = "string".class
if datatype == String
puts "This will print"
end
is not the same as
case datatype
when String
puts "This will NOT print"
end
Upvotes: 5
Views: 524
Reputation: 1912
You could also use the explicit form of case statement
datatype = test_object.class
case
when datatype == String
puts "It's a string"
when datatype < Numeric
puts "It's a number"
end
Note that the expression datatype < Numeric will be true for all numeric types.
Upvotes: 1
Reputation: 6041
Similar to Aleksei Matiushkin's answer, but without the curry:
is_class = ->(klass) { ->(item) { item == klass } }
10.times do
case ['abc', 123].sample.class
when is_class[String]
puts "it's the abc"
when is_class[Integer]
puts "easy as 123"
end
end
What happens here?
proc[x]
is the same as proc.call(x)
proc.===(x)
is the same as proc.call(x)
is_class[Integer]
returns a proc that does { |val| val == Integer }
===
==> call
.The big downside is it creates a lot of procs and looks weird.
Of course the obvious solution to your question would be to not do datatype = "string".class
:
datatype = "string"
case datatype
when String
puts "This will print"
end
Upvotes: 2
Reputation: 121000
This would be a more concise and cleaner (IMSO) approach to what @sawa had suggested. Use λ instead of the wrapper class.
META = ->(type, receiver) { receiver == type }
case "string".class
when META.curry[Integer] then puts 'integer'
when META.curry[String] then puts 'string'
end
#⇒ "string"
This solution uses Proc#curry
and Proc#===
under the hood.
Upvotes: 3
Reputation: 168101
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
Upvotes: 4