Perché i procs possono essere invocati con=== in Ruby 1.9?
-
12-12-2019 - |
Domanda
Questo articolo menziona 4 modi per invocare Procsin Ruby 1.9, e=== è uno di loro.Non capisco perché questo sarebbe stato fatto in questo modo.Ha alcuna relazione con il significato normale di=== (chiedendo se i due oggetti sono lo stesso oggetto)?
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, #].
Soluzione
Questo è ciò che i documenti devono dire :
.È per consentire a un oggetto PROC di essere un obiettivo della clausola
when
nel Dichiarazione del caso.
Questo è un, forse inventato, esempio:
even = proc { |x| x % 2 == 0 }
n = 3
case n
when even
puts "even!"
else
puts "odd!"
end
.
funziona perché il case/when
è fondamentalmente eseguito come questo:
if even === n
puts "even!"
else
puts "odd!"
end
.
Il case/when
controlla quale ramo da eseguire chiamando ===
sugli argomenti alle clausole when
, raccogliendo il primo che restituisce un valore di verità.
Nonostante la sua somiglianza con l'operatore di uguaglianza (==
) non è una forma più forte o più debole di esso. Provo a pensare all'operatore ===
come l'operatore "appartiene a". Class
lo definisce in modo da poter controllare se un oggetto appartiene a la classe (ad esempio è un'istanza della classe o una sottoclasse della classe), Range
lo definisce da verificare se l'argomento Appartiene a la gamma (cioè è inclusa nella gamma), e così via. Questo non rendi davvero il caso Proc
ha più senso, ma la pensa come uno strumento per creare i tuoi appartiene a operatori, come il mio esempio sopra; Ho definito un oggetto che può determinare se qualcosa appartiene a il set di numeri pari.
Altri suggerimenti
Nota che ===
in Ruby non riguarda l'uguaglianza, a differenza di JavaScript.È usato specificamente per caso espressioni :
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
. Questa funzione è utile in caso di costruzione, quando è necessario calcolare qualcosa al confronto.
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
. .ha alcuna relazione con il significato normale di=== (chiedendo se i due oggetti sono lo stesso oggetto)?
In realtà, questo è un malinteso comune su ===
in Ruby.In realtà non è rigorosamente per il confronto Object#object_id
(anche se questo è il suo comportamento in molte invocazioni comuni).In Ruby, ===
è Case Supbito .
Ecco la descrizione di ===
da Object
: "Case uguaglianza - per oggetto classe, efficacemente lo stesso
come chiamante #==, ma in genere sovrascritto dai discendenti
Per fornire semantica significativa nelle dichiarazioni del caso. "
Purtroppo, anche se è composto da tre =
, non ha nulla nemmeno da remoto a fare con l'uguaglianza MrGreen