C'è differenza tra::E .quando si chiamano metodi di classe in Ruby?
Domanda
Domanda semplice, ma che mi ha incuriosito... c'è una differenza funzionale tra i seguenti due comandi?
String::class
String.class
Entrambi fanno quello che mi aspetto: cioè ritornano Class
- ma qual è la differenza tra l'utilizzo di ::
e il .
?
Ho notato che su quelle classi in cui sono definite costanti, il completamento automatico di IRB restituirà le costanti come opzioni disponibili quando si preme tab dopo ::
ma non dopo .
, ma non so quale sia il motivo...
Soluzione
IL .
l'operatore dice fondamentalmente "invia questo messaggio all'oggetto".Nel tuo esempio sta chiamando quel particolare membro.IL ::
L'operatore esegue il drill-down nell'ambito definito a sinistra dell'operatore, quindi chiama il membro definito sul lato destro dell'operatore.
Quando usi ::
devi fare riferimento a membri definiti.Quando si usa .
stai semplicemente inviando un messaggio all'oggetto.Poiché il messaggio potrebbe essere qualsiasi cosa, il completamento automatico non funziona .
mentre lo fa per ::
.
Altri suggerimenti
In realtà, il completamento automatico funziona per .
.Le opzioni di completamento si trovano chiamando #methods
sull'oggetto.Puoi vederlo tu stesso eseguendo l'override Object.methods
:
>> def Object.methods; ["foo", "bar"]; end
=> nil
>> Object.[TAB]
Object.foo Object.bar
>> Object.
Tieni presente che funziona solo quando l'espressione a sinistra di .
è un valore letterale.Altrimenti, ottenere l'oggetto da chiamare #methods
Ciò comporterebbe la valutazione del lato sinistro, il che potrebbe avere effetti collaterali.Puoi vederlo anche tu stesso:
[continuing from above...]
>> def Object.baz; Object; end
=> nil
>> Object.baz.[TAB]
Display all 1022 possibilities? (y or n)
Aggiungiamo un metodo #baz
A Object
che ritorna Object
si.Quindi completiamo automaticamente per ottenere i metodi a cui possiamo fare appello Object.baz
.Se l'IRB avesse chiamato Object.baz.methods
, otterrebbe la stessa cosa di Object.methods
.Invece, l’IRB ha 1022 suggerimenti.Non sono sicuro da dove provengano, ma è chiaramente un elenco generico che in realtà non è basato sul contesto.
IL ::
l'operatore è (anche) utilizzato per ottenere le costanti di un modulo, mentre .
non è.Ecco perché HTTP
verrà visualizzato nel completamento di Net::
, ma non per Net.
. Net.HTTP
non è corretto, ma Net::HTTP
È.