u = User.find 24
=> #<User:0x3ead8c8…
u === User
=> false
User === u
=> true
–
David A., el único desarrollador con una orden de alejamiento de
Jeffrey Zeldman Simplelogica.net, ahora con un 33,3% más de intromisión en listas de correo
por lo que se esta ejecutando el metodo de clase ===. Si User no lo
ha redefinido hereda el de Module, que dice si u es instancia o no de
User (lo es).
En cambio
u === User
ejecuta u.===(User), que si no lo ha redefinido pilla el de Object,
que es equivalente a Object#==. Como u y User son objetos distintos,
devuelve false.
El Thursday 15 February 2007 11:15:59 David A.
escribió:>
=> true
En el primer caso, estás invocando al método === del objeto ‘u’; en el
segundo, estás invocando al método === el objeto ‘User’ (que es una clase).
En el primer caso, será verdadero si ‘u’ y ‘User’ son iguales (que no es
el
caso). En el segundo caso, será verdadero si ‘u’ es de la clase ‘User’
(algo
que es cierto).
El método ‘===’ es una de esas cosas de Ruby que me encantan. Se trata de
un
método de Object que cada descendiente (Object es la clase ‘padre’ de
todas
las clases en Ruby) redefine según tenga sentido para ella. Object#== y
Object#=== son equivalentes.
Pero por ejemplo, en el caso de Range#=== se comporta como
Range#member?; es
decir, será verdadero si el objeto que le pasamos como parámetro se
encuentra
dentro del rango en
cuestión.
Esto le da un nuevo sentido a la estructura ‘case’, ya que es
precisamente
este método el que se utiliza a la hora de comparar:
case 79
when 1…50 then print “low\n”
when 51…75 then print “medium\n”
when 76…100 then print “high\n”
end
En este ejemplo de la documentación, el resultado será “high”, ya que lo que
hace es invocar a (1…50) === 79, (51…75) === 79 y (76…100) === 79.
Y en este caso, ¿cuál será el resultado? Lo dejo como ejercicio, aunque es
muy
facilito.
cadena = “una cadena”
case cadena
when String then print “clase”
when “una cadena” then print “cadena”
end
Saludos.
–
Imobach González Sosa
Servicio de Informática y Comunicaciones
Universidad de Las Palmas de Gran Canaria
Teléfono: +34 928457067
Correo-e: igonzalezs en pas.ulpgc.es
Primero para fijar el tiro, esto no viene causado por Rails sino por
Ruby, y te darÃa lo mismo si haces la prueba con una clase estándar, tal
que String.
En el primer caso estás invocando al === de Object, que te da cierto
básicamente si los dos objetos son el mismo (salvo sobrecargas en
subclases)
En el primer caso estás invocando al === de Object, que te da cierto
básicamente si los dos objetos son el mismo (salvo sobrecargas en
subclases)
por si he “malguiado” a alguien con mi deformación profesional, en Ruby
no se sobrecargan los métodos.
Una vez reescrito un método, independientemente de que la signatura sea
diferente por el tipo de los parámetros, ya he perdido el método
original de esa clase (a no ser que previamente haga un alias, y siempre
teniendo disponible el método si lo hubiera de la clase padre mediante
super)
gracias por el toque fxn
Estamos de estreno… si necesitas llevar el control de tus gastos
visita http://www.gastosgem.com !!Es gratis!!
ejecuta u.===(User), que si no lo ha redefinido pilla el de Object,
que es equivalente a Object#==. Como u y User son objetos distintos,
devuelve false.
Muchas gracias Xavier,
¿Debería redefinir entonces === en la clase User o me replanteo la
forma de hacer las cosas?
–
David A., el único desarrollador con una orden de alejamiento de
Jeffrey Zeldman Simplelogica.net, ahora con un 33,3% más de intromisión en listas de correo
El método ‘===’ es una de esas cosas de Ruby que me encantan. Se trata de un
método de Object que cada descendiente (Object es la clase ‘padre’ de todas
las clases en Ruby) redefine según tenga sentido para ella. Object#== y
Object#=== son equivalentes.
Gracias
Lo que no entiendo muy bien es porqué Object#=== es lo mismo que
Object#== ¿no sería mejor que Object#=== comprobara si el parámetro y
el objeto son de la misma clase? (supongo que hay una razón, pero no
la veo ahora mismo)
Un saludo
David A., el único desarrollador con una orden de alejamiento de
Jeffrey Zeldman Simplelogica.net, ahora con un 33,3% más de intromisión en listas de correo
ejecuta u.===(User), que si no lo ha redefinido pilla el de Object,
que es equivalente a Object#==. Como u y User son objetos distintos,
devuelve false.
Muchas gracias Xavier,
¿Debería redefinir entonces === en la clase User o me replanteo la
forma de hacer las cosas?
=== esta pensado para ser usado en las clausulas when de los case
statements (ni idea de como decir “statement” en castellano). Como
sabes Ruby lo usa alli transparentemente, por ello === no suele
invocarse directamente. Habria que redefenirlo o no en funcion de eso.
=== esta pensado para ser usado en las clausulas when de los case
statements (ni idea de como decir “statement” en castellano). Como
sabes Ruby lo usa alli transparentemente, por ello === no suele
invocarse directamente. Habria que redefenirlo o no en funcion de eso.
Me parece estupenda esa característica de Ruby, el único problema es
cuando, por temas de namespaces, no puedo acceder a una clase desde un
módulo (es decir, no puedo hacer un case para comprobar la clase
porque User no existe en el módulo que estoy haciendo).
Pensé en hacer algo tal que
así:
def ===(objeto)
self.class == objeto.class || self.class == objeto ||
self.class.to_s == objeto
end
Para poder utilizarlo tal que
así:
case objeto
when “User” …
when “Thing” …
end
Aunque me parece un pelín peligrosillo, así que al final cambiaré la
forma de hacer las cosas
Gracias a todos
David A., el único desarrollador con una orden de alejamiento de
Jeffrey Zeldman Simplelogica.net, ahora con un 33,3% más de intromisión en listas de correo
=== esta pensado para ser usado en las clausulas when de los case
statements (ni idea de como decir “statement” en castellano). Como
sabes Ruby lo usa alli transparentemente, por ello === no suele
invocarse directamente. Habria que redefenirlo o no en funcion de
eso.
Me parece estupenda esa característica de Ruby, el único problema es
cuando, por temas de namespaces, no puedo acceder a una clase desde un
módulo
A que te refieres? Sabes que puedes usar nombres fully-qualified para
acceder a cualquier namespace desde cualquier otro?
Lo que no entiendo muy bien es porqué Object#=== es lo mismo que
Object#== ¿no sería mejor que Object#=== comprobara si el parámetro y
el objeto son de la misma clase? (supongo que hay una razón, pero no
la veo ahora mismo)
Porque en el caso de Object, tiene que proveer la implementacion mas
generica posible, pues tambien será empleada por todas las otras
subclases. Por ejemplo, dejaria de funcionar (apropiadamente) para
String.
Mientras que para Class es posible pensar en una implementacion mas
util (comparar objeto con clase, en lugar de clase con clase). Para
Range tambien hay buen uso.
A que te refieres? Sabes que puedes usar nombres fully-qualified para
acceder a cualquier namespace desde cualquier otro?
Sí, gracias Xavier, lo que no se es cuál es el nombre fully-qualified
de un modelo dentro de una aplicación Rails.
David A., el único desarrollador con una orden de alejamiento de
Jeffrey Zeldman Simplelogica.net, ahora con un 33,3% más de intromisión en listas de correo
Porque en el caso de Object, tiene que proveer la implementacion mas
generica posible, pues tambien será empleada por todas las otras
subclases. Por ejemplo, dejaria de funcionar (apropiadamente) para
String.
Hola Sebastián,
No veo porqué es apropiado ese comportamiento para String, perdona si
es obvio pero hoy estoy de un espeso…
¿No parece lógico esto?
“hola” === String
=> true
Quizá sólo me parezca lógico porque vengo de programar en PHP o Java,
porque si lo piensas bien esos dos objetos son de distinto tipo, es
uno de los inconvenientes (a nivel de expresividad del lenguaje) de
que las clases sean objetos ¿no es
así?–
David A., el único desarrollador con una orden de alejamiento de
Jeffrey Zeldman Simplelogica.net, ahora con un 33,3% más de intromisión en listas de correo
La forma como yo la entendi es que el operador == se traduce en “es
igual a”, mientras que === se traduce en simplemente “es” (aunque
para complicarlo un poco, el orden de los operadores es inverso, es
decir, a === b se lee como “b es a?”).
Es decir, el == es mas estricto, mientras que === es mas flexible (y
a veces ingenioso) en su interpretacion de igualdad. Pero esto
implica que como es mas flexible, no es simetrico o bidireccional.
Mira estos ejemplos:
variable == “prueba” # digamos que es cierto: “el contenido de
variable es igual a prueba”
variable == String # falso, “el contenido de variable NO es
igual a la clase String”
variable.class == String # cierto, “la clase del contenido de
variable es igual a la clase String”
String === variable # cierto, “el contenido de variable es clase
String”
“prueba” === variable # cierto, “el contenido de variable es prueba”
variable === String # falso, “la clase String NO es prueba”
Y es importante entender ademas que el diseño de === no es
perfecto… yo ya me tope con un caso donde Ruby no respondio como me
lo esperaba: un metodo que recibia como parametro una clase, sobre la
cual debia hacer operaciones condicionales:
when variable_que_contiene_clase
case String
case Numeric
end
No funcionaba… porque variable_que_contiene_clase no es de clase
String, es de clase Class. Ese es un caso en que tanto a == b como b
== a son ciertos, pero fallan a===b y b===a.
Intenta con TuModulo::TuSubModulo::TuClase… o si no, con un ::
por delante, para asegurarte que lo busque en la raiz del espacio de
nombres (que deberia ser lo mismo, pero que a veces no lo es).
Si todos tus require’s aparecen fuera de tus modulos o clases,
entonces tus modulos o clases deberian estar definidos en ::
Intenta con TuModulo::TuSubModulo::TuClase… o si no, con un ::
por delante, para asegurarte que lo busque en la raiz del espacio de
nombres (que deberia ser lo mismo, pero que a veces no lo es).
Gracias a ti y a Xavier, ha funcionado perfectamente
David A., el único desarrollador con una orden de alejamiento de
Jeffrey Zeldman Simplelogica.net, ahora con un 33,3% más de intromisión en listas de correo
Porque tecnicamente, no es sobrecarga… sobrecarga es cuando tienes
varios metodos con distintos tipos de parametros o retornos… En
ruby no hay tipos, asi que no puedes sobrecargar.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.