¿Por qué se pueden invocar procs con === en Ruby 1.9?
-
12-12-2019 - |
Pregunta
Este artículo menciona 4 formas de invocar procs en Ruby 1.9, y === es una de ellas.No entiendo por qué esto se haría de esta manera.¿Tiene alguna relación con el significado normal de === (preguntar si los dos objetos son el mismo objeto)?
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, #]
Solución
Esto es lo que los médicos tienen que decir.:
Es para permitir que un objeto proc sea un objetivo de
when
cláusula en la declaración de caso.
Este es un ejemplo, quizás artificial:
even = proc { |x| x % 2 == 0 }
n = 3
case n
when even
puts "even!"
else
puts "odd!"
end
Funciona porque el case/when
básicamente se ejecuta así:
if even === n
puts "even!"
else
puts "odd!"
end
El case/when
comprueba qué rama ejecutar llamando ===
sobre los argumentos para when
cláusulas, eligiendo la primera que devuelva un valor veraz.
A pesar de su similitud con el operador de igualdad (==
) no es una forma más fuerte o más débil.Intento pensar en el ===
operador como el operador "pertenece a". Class
lo define para que puedas comprobar si un objeto pertenece a la clase (es decires una instancia de la clase o una subclase de la clase), Range
lo define como para comprobar si el argumento pertenece a el rango (es decirestá incluido en la gama), etc.Esto realmente no hace que Proc
caso tiene más sentido, pero considérelo como una herramienta para crear el suyo propio. pertenece a operadores, como mi ejemplo anterior;Definí un objeto que puede determinar si algo pertenece a el conjunto de los números pares.
Otros consejos
Tenga en cuenta que ===
en Ruby NO se trata de igualdad, a diferencia de JavaScript.Se utiliza específicamente para expresiones de caso:
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
Esta característica es útil en la construcción de casos, cuando necesite calcular algo en la comparación.
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
¿Tiene alguna relación con el significado normal de === (preguntar si los dos objetos son el mismo objeto)?
En realidad, esa es una idea errónea común sobre ===
en Rubí.En realidad no es estrictamente para Object#object_id
comparación (aunque ese es su comportamiento en muchas invocaciones comunes).En Rubí, ===
es el caso subsunción.
Aquí está la descripción de ===
de Object
:"Igualdad de casos: para el objeto de clase, efectivamente lo mismo que llamar a #==, pero generalmente anulado por los descendientes a proporcionar semántica significativa en las declaraciones de casos".
Lamentablemente, aunque se compone de tres =
, no tiene nada que ver ni remotamente con la igualdad :-D