2012-03-12 8 views
6

This article menciones 4 modos de invocar procsos en Ruby 1.9 y === es uno de ellos. No entiendo por qué esto se haría de esta manera. ¿Tiene alguna relación con el significado normal de === (preguntando si los dos objetos son el mismo objeto)?¿Por qué se pueden invocar procs con === en ruby ​​1.9?

 
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, #] 

Respuesta

4

This is what the docs have to say:

Es permitir que un objeto proc para ser un blanco de when cláusula en la declaración caso.

Ésta es una, tal vez artificial, ejemplo:

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

Funciona porque la case/when es básicamente ejecutados de esta manera:

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

Los case/when cheques que se ramifican para ejecutar llamando === en los argumentos a when cláusulas, recogiendo el primero que devuelve un valor Truthy.

A pesar de su similitud con el operador de igualdad (==) que no es una forma más fuerte o más débil de la misma. Intento pensar en el operador === como el operador "pertenece a". Class lo define para que pueda verificar si un objeto pertenece a la clase (es decir, es una instancia de la clase o una subclase de la clase), Range lo define como para verificar si el argumento pertenece a rango (es decir está incluido en el rango), y así sucesivamente. Esto realmente no hace que el caso Proc tenga más sentido, pero piense en ello como una herramienta para hacer que su propio pertenezca a operadores de, como mi ejemplo anterior; He definido un objeto que puede determinar si algo pertenece a el conjunto de los números pares.

+0

Oh los extremos a los que rubí vale con tal de tener buen caso/Cuando los bloques :-) 'String ===" foo "=> true' –

5

Tenga en cuenta que === en Ruby no se trata de igualdad, a diferencia de JavaScript. Se utiliza específicamente for case expressions:

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 
+0

Genial, pero tipo de _odd_. – user2398029

+0

@louism No es más extraño, IMO, que usar regex en una declaración de caso (el equivalente a Enumerable # grep) o que usar un bloque para 'Enumerable # select'. – Phrogz

2

Esta característica es útil en caso de construcción, cuando se necesita para 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 
+0

Hmm ... hice mi edición antes de que @theo agregara algo similar a su respuesta ... GMTA –

+0

@John Bachir, no creo que su edición sea buena para describir la idea de lambda en caso de construcción – megas

0

¿Cuenta con alguna relación con el significado normal de === (preguntando si los dos objetos son el mismo objeto)?

En realidad, esa es una idea falsa común sobre === en Ruby. En realidad, no es estrictamente para la comparación Object#object_id (aunque ese es su comportamiento en muchas invocaciones comunes). En Ruby, === es el caso subsumption.

Aquí está la descripción de === de Object: "Caso Igualdad - Para la clase Object, efectivamente el mismo como llamar # ==, pero por lo general anulados por los descendientes para proporcionar una semántica significativa en los estados de casos."

Lamentablemente, a pesar de que se compone de tres =, que no tiene nada ni remotamente que ver con la igualdad: -D

Cuestiones relacionadas