Вопрос:

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

ruby duck-typing case-statement

38431 просмотра

5 ответа

2578 Репутация автора

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

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

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

Автор: David Hollman Источник Размещён: 11.10.2010 05:07

Ответы (5)


1 плюс

113736 Репутация автора

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

t = 5

тогда

t.class == Fixnum

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

t = Array

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

t.class == Class

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

Автор: Jack Размещён: 11.10.2010 05:11

214 плюса

28707 Репутация автора

Решение

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

case item
when MyClass
...

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

Автор: Nakilon Размещён: 11.10.2010 05:11

5 плюса

45415 Репутация автора

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

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

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

Автор: Ken Bloom Размещён: 11.10.2010 05:22

54 плюса

7548 Репутация автора

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

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

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

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

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

Автор: Fred Размещён: 11.10.2010 05:37

10 плюса

11464 Репутация автора

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

case item.class.to_s
    when 'MyClass'

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

case item
    when MyClass

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

Автор: user664833 Размещён: 09.04.2015 11:24
32x32