Использование объекта класса в операторе case - PullRequest
13 голосов
/ 02 марта 2012

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

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

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

Ответы [ 4 ]

14 голосов
/ 05 марта 2012

Я бы не использовал 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
11 голосов
/ 02 марта 2012

Проблема с использованием чего-то подобного:

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

заключается в том, что он полностью пропускает подклассы, поэтому вы можете получить что-то, что является String, но пропущено вашей первой веткой.Кроме того, name будет лучшим выбором, чем to_s, поскольку семантически вы проверяете имя класса, а не его строковое представление;результат может быть таким же, но case a.name будет более понятным.

Если вы хотите использовать case и иметь дело с подклассами, тогда вы можете использовать Module#<= следующим образом:

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

Да, вы должны повторять a в каждом when, но именно так работает case.

0 голосов
/ 01 июля 2015

Потому что

Array === Array # return false

и «случай, когда» означает «===», так что вы столкнулись с проблемой.

0 голосов
/ 02 марта 2012

Мой временный ответ - использовать to_s, но я не уверен, что это лучшее, что можно сделать.В ожидании лучших ответов.

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