Использование объекта класса в выражении case
Каков наилучший способ использования объекта класса в case-заявлении? Предположим, что у меня есть a
, который является экземпляром класса Class
. Я хочу сопоставить его с разными классами. Если я делаю
case a
when String then ...
when Fixnum then ...
end
это не даст ожидаемого результата, потому что даже если a == String
, например, a === String
не является истинным. Каков умный способ сделать это?
Ответы
Ответ 1
Я бы не использовал to_s
, потому что "String".to_s
был бы "String"
, поэтому, возможно, я бы сделал
case
when a == String then ...
when a == Fixnum then ...
end
или
a = String
case [a]
when [String] then puts "String"
when [Array] then puts "Array"
end
Ответ 2
Проблема с использованием чего-то вроде этого:
case a.to_s
when "String" then ...
when "Fixnum" then ...
end
заключается в том, что он полностью пропускает подклассы, поэтому вы можете получить что-то, что является строкой, но пропущено вашей первой ветвью. Кроме того, name
был бы лучшим выбором, чем to_s
, поскольку семантически вы тестируете имя класса, а не его строковое представление; результат может быть таким же, но case a.name
будет более понятным.
Если вы хотите использовать case
и иметь дело с подклассом, вы можете использовать Module#<=
следующим образом:
case
when a <= String then ...
when a <= Fixnum then ...
end
Да, вам нужно повторить a
в каждом when
, но как раз работает case
.
Ответ 3
Мой временный ответ заключается в использовании to_s
, но я не уверен, что это лучшее, что можно сделать. Ожидание лучших ответов.
case a.to_s
when "String" then ...
when "Fixnum" then ...
end
Ответ 4
Поскольку
Array === Array # return false
и "case when" означает "===", поэтому вы сталкиваетесь с проблемой.