2010-09-21 10 views

risposta

21

confronti caso d'uso === piuttosto che ==. Per molti oggetti il ​​comportamento di === e == è lo stesso, vedi Numeric e String:

5 == 5 #=> true 
5 === 5 #=> true 

"hello" == "hello" #=> true 
"hello" === "hello" #=> true 

Ma per altri tipi di oggetto === può significare molte cose, del tutto a seconda del ricevente.

Per il caso di classi, === verifica se un oggetto è un'istanza di tale classe:

Class === Class.new #=> true. 

Per Gamma controlla se un oggetto cade in quell'intervallo:

(5..10) === 6 #=> true 

Per Procs , === effettivamente invoca che Proc:

multiple_of_10 = proc { |n| (n % 10) == 0 } 
multiple_of_10 === 20 #=> true (equivalent to multiple_of_10.call(20)) 

Per altri oggetti, verificare la loro definizione di === per scoprire il loro comportamento. Non è sempre evidente, ma di solito fanno un qualche tipo di senso ..

Ecco un esempio Mettere tutto insieme:

case number 
when 1 
    puts "One" 
when 2..9 
    puts "Between two and nine" 
when multiple_of_10 
    puts "A multiple of ten" 
when String 
    puts "Not a number" 
end 

Vedere questo link per maggiori informazioni: http://www.aimred.com/news/developers/2008/08/14/unlocking_the_power_of_case_equality_proc/

+1

+1: Grazie per l'intuizione! – Rekin

+0

queste sono tutte informazioni molto utili, molte cose che non sapevo, ma non mi sento in grado di risolvere la mia confusione. Con 'a = Foo.new.class' e' b = Foo', sia 'a' che' b' sono impostati su 'Foo'; inoltre, 'a.class' e' b.class' sono 'Class'.Come mai 'a === b # => falso'? Secondo i documenti, 'Object # ===' è equivalente a '# ==' se non sottoposto a override. Cosa succede nel mio caso specifico? –

+0

@macek, perché (come ho detto) '===' * è * sovrascritto per le classi. Quindi 'Foo === Foo' restituirà false come' === 'in quel contesto controlla' is_a? 'E non l'uguaglianza retta. – horseyguy

2

Nella dichiarazione case, il confronto viene eseguito utilizzando l'operatore ===.

Quindi il codice viene tradotta al seguente:

case x 
when User === x 
    puts "Constant" 
when "User" === x 
    puts "string" 
else 
    puts "nothing" 
end 

classe diversa definiscono === in modo diverso:

La classe Class definiscono === in modo che verifica se l'operando di destra (x) è un'istanza della classe indicata dall'operando di sinistra (User). Quindi, non è una sorpresa che User === x sarà valutato come false. Invece, User === u (u = User.new) è true.

irb(main):001:0> class User 
irb(main):002:1> end 
=> nil 
irb(main):003:0> u = User.new 
=> #<User:0xb7a90cd8> 
irb(main):004:0> User === u.class 
=> false 
irb(main):005:0> User === u 
=> true 
+0

Ho appena scoperto che 'Utente === u' non è uguale a' u === Utente'. Questo sta diventando troppo confuso ... –

+1

@macek, '===' è definito dal ricevitore, 'User' è una classe e quindi ha una diversa (e speciale) definizione di' === 'per un oggetto arbitrario . Qualsiasi oggetto dato può implementare '===' come vogliono, vedi: 'class << u; def === (o); mette "ciao mondo e # {o} !!"; fine; fine' e poi: 'u === U # =>" ciao mondo e U !! "' – horseyguy