Existe uma diferença entre ::e .ao chamar os métodos da classe em Ruby?
Pergunta
Pergunta simples, mas que eu tenho curiosidade sobre...existe uma diferença funcional entre os dois comandos a seguir?
String::class
String.class
Ambos fazem o que eu esperava, isto é, eles voltam Class
- mas qual é a diferença entre usar o ::
e o .
?
Eu observe que nessas classes que têm constantes definidas, IRB auto-completação de irá retornar as constantes de opções disponíveis quando você pressiona tab depois de ::
mas não depois .
, mas eu não sei o que a razão para isso é...
Solução
O .
operador basicamente diz "envie essa mensagem para o objeto".No seu exemplo é chamar que determinado membro.O ::
operador "drills" para o âmbito definido para a esquerda do operador, e, em seguida, chama o membro definidos no lado direito do operador.
Quando você usa ::
você tem que ser a referência membros que são definidos.Quando utilizar .
você está simplesmente enviar uma mensagem para o objeto.Porque essa mensagem pode ser qualquer coisa, conclusão automática não funciona para .
enquanto ele não para ::
.
Outras dicas
Na verdade, conclusão automática não funciona para .
.A conclusão opções são encontradas chamando #methods
no objeto.Você pode ver isso por si mesmo, substituindo-se Object.methods
:
>> def Object.methods; ["foo", "bar"]; end
=> nil
>> Object.[TAB]
Object.foo Object.bar
>> Object.
Note que isto só funciona quando a expressão à esquerda do .
é um literal.Caso contrário, ficando o objecto de chamada de #methods
no envolveria a avaliação do lado esquerdo, o que pode ter efeitos secundários.Você pode ver isso por si mesmo, assim:
[continuing from above...]
>> def Object.baz; Object; end
=> nil
>> Object.baz.[TAB]
Display all 1022 possibilities? (y or n)
Vamos adicionar um método #baz
para Object
que retorna Object
em si.Em seguida, temos o auto-completar para obter os métodos que podemos chamar de no Object.baz
.Se IRB chamado Object.baz.methods
, ele iria ficar a mesma coisa que Object.methods
.Em vez disso, o IRB tem 1022 sugestões.Eu não tenho certeza de onde eles vêm, mas é claramente uma lista genérica, o que não é, na verdade, com base no contexto.
O ::
o operador é (também) utilizada para a obtenção de um módulo constantes, enquanto .
não é.Que é por isso HTTP
vai mostrar-se na conclusão de Net::
, mas não para Net.
. Net.HTTP
não é correto, mas Net::HTTP
é.