2008-09-04 6 views
24

Pregunta simple, pero que me ha llamado la atención ... ¿hay alguna diferencia funcional entre los dos comandos siguientes?¿Hay una diferencia entre :: y. al llamar a los métodos de clase en Ruby?

String::class 
String.class 

Ambos hacen lo que espero - es decir, vuelven Class - pero ¿cuál es la diferencia entre usar el :: y la .?

noto que en aquellas clases que tienen constantes definidas, la finalización automática del IRB devolverá las constantes como las opciones disponibles cuando se pulsa la pestaña después de :: pero no después de ., pero no sé cuál es la razón de esto es. ..

Respuesta

35

el operador . básicamente dice "enviar este mensaje al objeto". En su ejemplo, está llamando a ese miembro en particular. El operador :: "profundiza" hacia el alcance definido a la izquierda del operador, y luego llama al miembro definido en el lado derecho del operador.

Cuando se utiliza :: que tienen que ser miembros hacen referencia a que están definidos. Cuando usa ., simplemente está enviando un mensaje al objeto. Como ese mensaje podría ser cualquier cosa, la finalización automática no funciona para ., mientras que para ::.

11

En realidad, la finalización automática funciona para .. Las opciones de finalización se encuentran llamando al #methods en el objeto. Esto se puede ver por sí 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 de la . es un literal. De lo contrario, hacer que el objeto llame al #methods implicaría evaluar el lado izquierdo, lo que podría tener efectos secundarios. Esto se puede ver por sí mismo, así:

[continuing from above...] 
>> def Object.baz; Object; end 
=> nil 
>> Object.baz.[TAB] 
Display all 1022 possibilities? (y or n) 

Añadimos un método #baz a Object que devuelve Object sí. Luego, completamos automáticamente para obtener los métodos que podemos llamar en Object.baz. Si el IRB llama al Object.baz.methods, obtendría lo mismo que Object.methods. En cambio, 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 operador :: es (también) que se utiliza para obtener las constantes de un módulo, mientras que . no lo es. Es por eso que HTTP aparecerá en la finalización para Net::, pero no para Net.. Net.HTTP no es correcto, pero Net::HTTP es.

Cuestiones relacionadas