¿Hay alguna diferencia entre ::y .al llamar a métodos de clase en Ruby?
Pregunta
Pregunta simple, pero sobre la que he tenido curiosidad... ¿Existe alguna diferencia funcional entre los dos comandos siguientes?
String::class
String.class
Ambos hacen lo que espero, es decir, regresan. Class
-- pero ¿cuál es la diferencia entre usar el ::
y el .
?
Noto que en aquellas clases que tienen constantes definidas, el autocompletado de IRB devolverá las constantes como opciones disponibles cuando presiones tab después ::
pero no después .
, pero no sé cuál es la razón de esto...
Solución
El .
El operador básicamente dice "enviar este mensaje al objeto".En su ejemplo, está llamando a ese miembro en particular.El ::
El operador "profundiza" hasta el alcance definido a la izquierda del operador y luego llama al miembro definido en el lado derecho del operador.
cuando usas ::
tienes que hacer referencia a miembros que estén definidos.Cuando usas .
simplemente estás enviando un mensaje al objeto.Debido a que ese mensaje puede ser cualquier cosa, la función de autocompletar no funciona para .
mientras lo hace por ::
.
Otros consejos
En realidad, la función de autocompletar funciona para .
.Las opciones de finalización se encuentran llamando #methods
sobre el objeto.Puedes ver esto por ti mismo anulando Object.methods
:
>> def Object.methods; ["foo", "bar"]; end
=> nil
>> Object.[TAB]
Object.foo Object.bar
>> Object.
Tenga en cuenta que esto sólo funciona cuando la expresión a la izquierda del .
es un literal.De lo contrario, hacer que el objeto llame #methods
implicaría evaluar el lado izquierdo, lo que podría tener efectos secundarios.También puedes ver esto por ti mismo:
[continuing from above...]
>> def Object.baz; Object; end
=> nil
>> Object.baz.[TAB]
Display all 1022 possibilities? (y or n)
Agregamos un método #baz
a Object
que regresa Object
sí mismo.Luego completamos automáticamente para obtener los métodos a los que podemos recurrir. Object.baz
.Si el IRB llamó Object.baz.methods
, obtendría lo mismo que Object.methods
.En cambio, el IRB tiene 1022 sugerencias.No estoy seguro de dónde vienen, pero es claramente una lista genérica que en realidad no se basa en el contexto.
El ::
El operador (también) se usa para obtener las constantes de un módulo, mientras que .
no es.Es por eso HTTP
aparecerá en la finalización de Net::
, pero no para Net.
. Net.HTTP
no es correcto, pero Net::HTTP
es.