How do I use a case statement and check for two conditions?
I need to check that an item is an array and only contains string classes.
a = ['one','twon'] # => ["one", "twon"]
case a # =>
when String
puts "string
when Array && a.all?{|obj| obj.is_a?(String) }
puts 'an array with only string classes'
else
raise ArgumentError, "unsupported object #{obj}:#{obj.class}"
end
The above code returns the else
case, when it should be returning the "an array with only string classes" statement
The conditions in a case
statement are not Boolean expressions; they are values that are compared against the target object using the ===
operator. Of course, any class can override that operator, but the predefined one only returns true for a small set of conditions (like is_a?
, equals, is contained in, =~
...). Having a Boolean expression as the when
condition doesn't trigger a match when that expression is true; it triggers a match when the target object ===
the value of the expression, and for most objects, obj === true
is not itself true.
So you might want to swap out your case
for an if
/ else
chain in this instance:
if a.is_a? String
puts 'string'
elsif a.is_a?(Array) && a.all? { |obj| obj.is_a? String }
puts 'an array with only string classes'
else
raise ArgumentError, "unsupported object #{a}:#{a.class}"
end
Or do a nested check inside the case condition. But then you would have two else
states, one for the if
(meaning it matched the array case but wasn't all strings) and one for the case
(meaning it was something else entirely). So rather than duplicate the error-handling code like that, I used a boolean variable to indicate when an error needed to be raise
d:
ok = false
case a
when String
puts 'string'
ok = true
when Array
if a.all? { |obj| obj.is_a? String }
puts 'an array with only string classes'
ok = true
end
end
if !ok
raise ArgumentError, "unsupported object #{a}:#{a.class}"
end
Use pattern-matching!
a = ['one','twon']
case a
in String
puts 'string'
in Array if a.all?(String)
puts 'an array with only string classes'
else
raise ArgumentError, "unsupported object #{a}:#{a.class}"
end
* ruby 2.7+
** experimental feature
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.