Question

Cet article mentionne 4 façons d'invoquer des procs dans Ruby 1.9, et === en fait partie.Je ne comprends pas du tout pourquoi cela se ferait de cette façon.Cela a-t-il un rapport avec la signification normale de === (demander si les deux objets sont le même objet) ?

irb(main):010:0> f =-> n {[:hello, n]}
=> #
irb(main):011:0> f.call(:hello)
=> [:hello, :hello]
irb(main):012:0> f === :hello
=> [:hello, :hello]
irb(main):013:0> Object.new === Object.new
=> false
irb(main):014:0> f === f
=> [:hello, #]
Était-ce utile?

La solution

C'est ce que disent les documents:

Il s'agit de permettre à un objet proc d'être la cible de when clause dans la déclaration de cas.

Ceci est un exemple, peut-être artificiel :

even = proc { |x| x % 2 == 0 }
n = 3
case n
when even
  puts "even!"
else
  puts "odd!"
end

Cela fonctionne parce que le case/when est essentiellement exécuté comme ceci :

if even === n
  puts "even!"
else
  puts "odd!"
end

Le case/when vérifie quelle branche exécuter en appelant === sur les arguments à when clauses, en choisissant la première qui renvoie une valeur véridique.

Malgré sa similitude avec l'opérateur d'égalité (==) ce n’est pas une forme plus forte ou plus faible.J'essaie de penser à === comme opérateur "appartient à". Class le définit afin que vous puissiez vérifier si un objet appartient à la classe (c'est-à-direest une instance de la classe ou une sous-classe de la classe), Range le définit comme pour vérifier si l'argument appartient à la plage (c'est-à-direest inclus dans la gamme), et ainsi de suite.Cela ne rend pas vraiment le Proc cas a plus de sens, mais considérez-le comme un outil pour créer le vôtre appartient à opérateurs, comme mon exemple ci-dessus ;J'ai défini un objet qui peut déterminer si quelque chose appartient à l'ensemble des nombres pairs.

Autres conseils

Notez que === dans Ruby ne concerne pas l'égalité, contrairement à JavaScript.Il est spécifiquement utilisé pour les expressions de cas :

case cats.length
  when 42                         # Uses 42      === cats.length
    puts :uh
  when /cool/i                    # Uses /cool/i === cats.length
    puts :oh
  when ->(n){ n.odd? || n/3==6 }  # Passes cats.length to the proc
    puts :my
end

Cette fonctionnalité est utile dans le cas de la construction, lorsque vous devez calculer quelque chose à la comparaison.

is_odd  =-> n { n%2 != 0 }
is_even =-> n { n%2 == 0 }

case 5
when is_even
  puts "the number is even"
when is_odd
  puts "the number is odd"
end

=> the number is odd

Cela a-t-il un rapport avec la signification normale de === (demander si les deux objets sont le même objet) ?

En fait, c'est une idée fausse très répandue à propos === en Rubis.En fait, ce n'est pas strictement destiné Object#object_id comparaison (bien que ce soit son comportement dans de nombreuses invocations courantes).En Rubis, === c'est le cas subsomption.

Voici la description de === depuis Object:"Égalité de cas - pour l'objet de classe, en fait la même chose que l'appel # ==, mais généralement remplacé par les descendants de fournir une sémantique significative dans les instructions de cas."

Malheureusement, même s'il comprend trois =, cela n'a rien à voir, même de loin, avec l'égalité :-D

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top