Типы классов Ruby и операторы case

В чем разница между

case item.class
when MyClass
  # do something here
when Array
  # do something different here
when String
  # do a third thing
end

а также

case item.class
when MyClass.class
  # do something here
when Array.class
  # do something different here
when String.class
  # do a third thing
end

По какой-то причине первый из них иногда работает, а второй нет, а иногда - второй работает, а первый - нет. Зачем? Какой из них "правильный" способ сделать это?

5 ответов

Решение

Вы должны использовать:

case item
    when MyClass

У меня была такая же проблема: как отловить класс Errno::ECONNRESET в "случае, когда"?

Да, Накилон прав, вы должны знать, как работает оператор triqual === над объектом, указанным в when пункт. В рубине

case item
when MyClass
...
when Array
...
when String
...

действительно

if MyClass === item
...
elsif Array === item
...
elsif String === item
...

Поймите, что в этом случае вызывается тройной метод (MyClass.===(item) например), и этот метод может быть определен, чтобы делать все, что вы хотите, а затем вы можете использовать оператор case с PrecisionW

Ты можешь использовать:

case item.class.to_s
    when 'MyClass'

... когда следующий поворот невозможен:

case item
    when MyClass

Причина этого в том, что case использования === и отношения === Оператор описывает не коммутативно. Например, 5 является Integer, но это Integer 5? Вот как вы должны думать о case / when,

В Ruby имя класса является константой, которая ссылается на объект типа Class это описывает определенный класс. Это означает, что поговорка MyClass в Ruby эквивалентно поговорке MyClass.class на Яве.

obj.class является объектом типа Class описывая класс obj, Если obj.class является MyClass, затем obj был создан с использованием MyClass.new (грубо говоря). MyClass является объектом типа Class который описывает любой объект, созданный с использованием MyClass.new,

MyClass.class это класс MyClass объект (это класс объекта типа Class который описывает любой объект, созданный с использованием MyClass.new). Другими словами, MyClass.class == Class,

Это зависит от характера вашего item переменная. Если это экземпляр объекта, например

t = 5

затем

t.class == Fixnum

но если это класс сам по себе, например,

t = Array

тогда это будет Class объект, так

t.class == Class

РЕДАКТИРОВАТЬ: пожалуйста, обратитесь к Как поймать класс Errno::ECONNRESET в "случае, когда"? как заявил Накилон, так как мой ответ может быть неправильным.

Другие вопросы по тегам