2012-06-05 10 views
7

Per dare un piccolo contesto intorno a come ho capito il problema.Perché l'operatore splat/unario modifica il valore assegnato a quando p viene chiamato prima di * a = ""?

Utilizzando splat raccogliere su una stringa invia: to_a o: to_ary alla stringa

class String 
    def method_missing method, *args, &block 
    p method #=> :to_ary 
    p args #=> [] 
    p block #=> nil 
    end 
end 

*b = "b" 

Stavo pensando che ridefinire il: metodo di to_ary sarebbe quello che sto cercando.

class String 
    def to_ary 
    ["to_a"] 
    end 
end 

p *a = "a" #=> "a" 
p a  #=> "a" 

*b = "b" 
p b  #=> ["to_a"] 

Ora questo mi confonde a non finire.

La stampa del risultato da * a = "a" modifica il valore assegnato a a?

Per dimostrare ulteriormente

class String 
    def to_ary 
    [self.upcase!] 
    end 
end 

p *a = "a" #=> "a" 
p a  #=> "a" 

*b = "b" 
p b  #=> ["B"] 

risposta

9

domanda molto interessante! Rubino prende questa espressione:

p *a = "a" 

e lo traduce in qualcosa di simile a questo:

temp = (a = "a") 
p *temp 

Quindi la prima cosa che succede è che a viene assegnato a "a", e poi il risultato della cessione espressione che è "a" viene splattato e inviato a p. Poiché il comportamento predefinito di p quando si inviano più argomenti è sufficiente per ripetere e stampare ciascuno di essi, viene visualizzato solo "a".

In breve, segue un ordine di assegnazione "assegna quindi splat". Quindi a viene assegnato a "a" prima che la stringa venga splattata.

quando non si dispone di una chiamata di funzione tuttavia, è interpretato come qualcosa di simile a questo:

# *a = "a" gets interpreted as: 
temp = "a" 
a = *temp 

Questo segue un "splat quindi assegnare" ordine di valutazione. Quindi a viene assegnato dopo la stringa viene splattata.

Si può vedere ciò che è stato ricevuto da una funzione andando in questo modo:

def foo *args 
    puts args.inspect 
end 

foo *a = "a" # outputs ["a"] 
a    # outputs "a" 

Spero che questo chiarisce che cosa sta succedendo!

In breve (grazie a Mark Reed):

p *a = "a" # interpreted as: p(*(a = "a")) 
*a = "a"  # interpreted as: a = *("a") 
+1

destro. È tutto sulla precedenza. 'p * a =" a "' significa 'p (* (a =" a "))', non 'p (* a =" a ")'. –

+0

Sì, ho modificato per aggiungere un po 'di una nota di chiarimento. – robbrit

Problemi correlati