Подтвердить что ты не робот

Использование объекта класса в выражении case

Каков наилучший способ использования объекта класса в case-заявлении? Предположим, что у меня есть a, который является экземпляром класса Class. Я хочу сопоставить его с разными классами. Если я делаю

case a
when String then ...
when Fixnum then ...
end

это не даст ожидаемого результата, потому что даже если a == String, например, a === String не является истинным. Каков умный способ сделать это?

4b9b3361

Ответ 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" означает "===", поэтому вы сталкиваетесь с проблемой.