web-dev-qa-db-fra.com

Ruby types de classe et instructions case

Quelle est la différence entre

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

et

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

Pour une raison quelconque, le premier de ces travaux parfois et le second ne fonctionne pas, et d'autres fois, le second fonctionne et le premier ne fonctionne pas. Pourquoi? Laquelle est la façon "appropriée" de le faire?

124
David Hollman

Tu dois utiliser:

case item
when MyClass
...

J'ai eu le même problème: Comment attraper la classe Errno :: ECONNRESET dans "cas où"?

208
Nakilon

Oui, Nakilon a raison, vous devez savoir comment l'opérateur threequal === fonctionne sur l'objet donné dans la clause when. En rubis

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

est vraiment

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

Comprenez que la casse appelle une méthode threequal (MyClass.===(item) par exemple), et que cette méthode peut être définie pour faire ce que vous voulez, puis vous pouvez utiliser l'instruction case avec precisionw

54
Fred

Vous pouvez utiliser:

case item.class.to_s
    when 'MyClass'

... lorsque la torsion suivante n'est pas possible:

case item
    when MyClass

La raison en est que case utilise === et la relation entre le === L'opérateur décrit n'est pas commutatif . Par exemple, 5 est un Integer, mais est Integer a 5? Voici comment vous devriez penser à case/when.

9
user664833

Dans Ruby, un nom de classe est une constante qui fait référence à un objet de type Class qui décrit une classe particulière. Cela signifie que dire MyClass dans Ruby équivaut à dire MyClass.class en Java.

obj.class est un objet de type Class décrivant la classe de obj. Si obj.class est MyClass, puis obj a été créé à l'aide de MyClass.new (Grosso modo). MyClass est un objet de type Class qui décrit tout objet créé à l'aide de MyClass.new.

MyClass.class est la classe de l'objet MyClass (c'est la classe de l'objet de type Class qui décrit tout objet créé à l'aide de MyClass.new). En d'autres termes, MyClass.class == Class.

5
Ken Bloom

Cela dépend de la nature de votre variable item. S'il s'agit d'une instance d'un objet, par ex.

t = 5

puis

t.class == Fixnum

mais si c'est une classe en soi par exemple

t = Array

alors ce sera un objet Class, donc

t.class == Class

[~ # ~] éditez [~ # ~] : veuillez vous référer à Comment attraper la classe Errno :: ECONNRESET dans "cas où" ? comme indiqué par Nakilon car ma réponse pourrait être fausse.

1
Jack