Operadores de igualdad: == y! =
El operador ==, también conocido como igualdad o doble igualdad, devolverá verdadero si ambos objetos son iguales y falso si no lo son.
"koan" == "koan" # Output: => true
El operador! =, También conocido como desigualdad, es lo opuesto a ==. Devolverá verdadero si ambos objetos no son iguales y falso si son iguales.
"koan" != "discursive thought" # Output: => true
Tenga en cuenta que dos matrices con los mismos elementos en un orden diferente no son iguales, las versiones en mayúsculas y minúsculas de la misma letra no son iguales, etc.
Al comparar números de diferentes tipos (p. Ej., Entero y flotante), si su valor numérico es el mismo, == devolverá verdadero.
2 == 2.0 # Output: => true
¿igual?
A diferencia del operador == que prueba si ambos operandos son iguales, el método igual verifica si los dos operandos se refieren al mismo objeto. Esta es la forma más estricta de igualdad en Ruby.
Ejemplo: a = "zen" b = "zen"
a.object_id # Output: => 20139460
b.object_id # Output :=> 19972120
a.equal? b # Output: => false
En el ejemplo anterior, tenemos dos cadenas con el mismo valor. Sin embargo, son dos objetos distintos, con diferentes ID de objeto. Por lo tanto, el igual? El método devolverá falso.
Intentemos nuevamente, solo que esta vez b será una referencia a a. Observe que la ID del objeto es la misma para ambas variables, ya que apuntan al mismo objeto.
a = "zen"
b = a
a.object_id # Output: => 18637360
b.object_id # Output: => 18637360
a.equal? b # Output: => true
eql?
En la clase Hash, el eql? método se utiliza para probar claves para la igualdad. Se requieren algunos antecedentes para explicar esto. En el contexto general de la informática, una función hash toma una cadena (o un archivo) de cualquier tamaño y genera una cadena o número entero de tamaño fijo llamado hashcode, comúnmente conocido como solo hash. Algunos tipos de hashcode comúnmente utilizados son MD5, SHA-1 y CRC. Se utilizan en algoritmos de cifrado, indexación de bases de datos, comprobación de integridad de archivos, etc. Algunos lenguajes de programación, como Ruby, proporcionan un tipo de colección llamada tabla hash. Las tablas hash son colecciones tipo diccionario que almacenan datos en pares, que consisten en claves únicas y sus valores correspondientes. Debajo del capó, esas claves se almacenan como códigos hash. Las tablas hash se conocen comúnmente como solo hashes. Observe cómo la palabra hash puede referirse a un código hash o a una tabla hash.
Ruby proporciona un método incorporado llamado hash para generar códigos hash. En el siguiente ejemplo, toma una cadena y devuelve un código hash. Observe cómo las cadenas con el mismo valor siempre tienen el mismo código hash, aunque sean objetos distintos (con diferentes ID de objeto).
"meditation".hash # Output: => 1396080688894079547
"meditation".hash # Output: => 1396080688894079547
"meditation".hash # Output: => 1396080688894079547
El método hash se implementa en el módulo Kernel, incluido en la clase Object, que es la raíz predeterminada de todos los objetos Ruby. Algunas clases como Symbol e Integer usan la implementación predeterminada, otras como String y Hash proporcionan sus propias implementaciones.
Symbol.instance_method(:hash).owner # Output: => Kernel
Integer.instance_method(:hash).owner # Output: => Kernel
String.instance_method(:hash).owner # Output: => String
Hash.instance_method(:hash).owner # Output: => Hash
En Ruby, cuando almacenamos algo en un hash (colección), el objeto proporcionado como clave (por ejemplo, cadena o símbolo) se convierte y almacena como un código hash. Más tarde, al recuperar un elemento del hash (colección), proporcionamos un objeto como clave, que se convierte en un hashcode y se compara con las claves existentes. Si hay una coincidencia, se devuelve el valor del elemento correspondiente. La comparación se realiza utilizando el eql? método debajo del capó.
"zen".eql? "zen" # Output: => true
# is the same as
"zen".hash == "zen".hash # Output: => true
En la mayoría de los casos, el eql? El método se comporta de manera similar al método ==. Sin embargo, hay algunas excepciones. Por ejemplo, eql? no realiza conversión de tipo implícito al comparar un entero con un flotante.
2 == 2.0 # Output: => true
2.eql? 2.0 # Output: => false
2.hash == 2.0.hash # Output: => false
Operador de igualdad de casos: ===
Muchas de las clases integradas de Ruby, como String, Range y Regexp, proporcionan sus propias implementaciones del operador ===, también conocido como igualdad de casos, triples iguales o tres iguales. Debido a que se implementa de manera diferente en cada clase, se comportará de manera diferente dependiendo del tipo de objeto al que fue llamado. En general, devuelve verdadero si el objeto de la derecha "pertenece" o "es miembro del" objeto de la izquierda. Por ejemplo, se puede usar para probar si un objeto es una instancia de una clase (o una de sus subclases).
String === "zen" # Output: => true
Range === (1..2) # Output: => true
Array === [1,2,3] # Output: => true
Integer === 2 # Output: => true
Se puede lograr el mismo resultado con otros métodos que probablemente sean los más adecuados para el trabajo. Por lo general, es mejor escribir código que sea fácil de leer siendo lo más explícito posible, sin sacrificar la eficiencia y la concisión.
2.is_a? Integer # Output: => true
2.kind_of? Integer # Output: => true
2.instance_of? Integer # Output: => false
Observe que el último ejemplo devuelve falso porque los enteros como 2 son instancias de la clase Fixnum, que es una subclase de la clase Integer. El ===, es_a? e instancia_de? Los métodos devuelven verdadero si el objeto es una instancia de la clase dada o de cualquier subclase. El método instance_of es más estricto y solo devuelve verdadero si el objeto es una instancia de esa clase exacta, no una subclase.
El is_a? y kind_of? Los métodos se implementan en el módulo Kernel, que se mezcla con la clase Object. Ambos son alias del mismo método. Vamos a verificar:
Kernel.instance_method (: kind_of?) == Kernel.instance_method (: is_a?) # Salida: => true
Implementación de rango de ===
Cuando se llama al operador === en un objeto de rango, devuelve verdadero si el valor de la derecha cae dentro del rango de la izquierda.
(1..4) === 3 # Output: => true
(1..4) === 2.345 # Output: => true
(1..4) === 6 # Output: => false
("a".."d") === "c" # Output: => true
("a".."d") === "e" # Output: => false
Recuerde que el operador === invoca el método === del objeto de la izquierda. Entonces (1..4) === 3 es equivalente a (1..4). === 3. En otras palabras, la clase del operando de la izquierda definirá qué implementación del método === será llamado, por lo que las posiciones de los operandos no son intercambiables.
Implementación de expresiones regulares de ===
Devuelve verdadero si la cadena de la derecha coincide con la expresión regular de la izquierda. / zen / === "practica zazen hoy" # Salida: => verdadero # es lo mismo que "practica zazen hoy" = ~ / zen /
Uso implícito del operador === en declaraciones de caso / cuándo
Este operador también se utiliza bajo el capó en las declaraciones de caso / cuándo. Ese es su uso más común.
minutes = 15
case minutes
when 10..20
puts "match"
else
puts "no match"
end
# Output: match
En el ejemplo anterior, si Ruby hubiera usado implícitamente el operador de doble igualdad (==), el rango 10..20 no se consideraría igual a un número entero como 15. Coinciden porque el operador de triple igualdad (===) es implícitamente utilizado en todas las declaraciones de caso / cuándo. El código en el ejemplo anterior es equivalente a:
if (10..20) === minutes
puts "match"
else
puts "no match"
end
Operadores de coincidencia de patrones: = ~ y! ~
Los operadores = ~ (igual-tilde) y! ~ (Bang-tilde) se utilizan para unir cadenas y símbolos con patrones de expresiones regulares.
La implementación del método = ~ en las clases String y Symbol espera una expresión regular (una instancia de la clase Regexp) como argumento.
"practice zazen" =~ /zen/ # Output: => 11
"practice zazen" =~ /discursive thought/ # Output: => nil
:zazen =~ /zen/ # Output: => 2
:zazen =~ /discursive thought/ # Output: => nil
La implementación en la clase Regexp espera una cadena o un símbolo como argumento.
/zen/ =~ "practice zazen" # Output: => 11
/zen/ =~ "discursive thought" # Output: => nil
En todas las implementaciones, cuando la cadena o el símbolo coincide con el patrón Regexp, devuelve un número entero que es la posición (índice) de la coincidencia. Si no hay coincidencia, devuelve nulo. Recuerde que, en Ruby, cualquier valor entero es "verdadero" y nulo es "falso", por lo que el operador = ~ puede usarse en declaraciones if y operadores ternarios.
puts "yes" if "zazen" =~ /zen/ # Output: => yes
"zazen" =~ /zen/?"yes":"no" # Output: => yes
Los operadores de coincidencia de patrones también son útiles para escribir sentencias if más cortas. Ejemplo:
if meditation_type == "zazen" || meditation_type == "shikantaza" || meditation_type == "kinhin"
true
end
Can be rewritten as:
if meditation_type =~ /^(zazen|shikantaza|kinhin)$/
true
end
El operador! ~ Es lo opuesto a = ~, devuelve verdadero cuando no hay coincidencia y falso si hay coincidencia.
Más información está disponible en esta publicación de blog .
"a" == "a"
,"a" === "a"
y"a".eql? "a"
. Pero esto es falso:"a".equal? "a"
(El mío es rubí 1.9.2-p180)