2012-06-05 10 views
7

Para dar un pequeño contexto sobre cómo entiendo el problema.¿Por qué el operador splat/unary cambia el valor asignado a cuando se llama a p antes de * a = ""?

Usando splat recoger en una cadena envía: to_a o: to_ary a la cadena

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

*b = "b" 

así que estaba pensando que redefinir el: Método to_ary sería lo que busco.

class String 
    def to_ary 
    ["to_a"] 
    end 
end 

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

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

Ahora esto me confunde hasta el final.

Imprimir el resultado de * a = "a" cambia el valor asignado a?

Para demostrar aún más

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

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

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

Respuesta

9

pregunta muy interesante! Rubí toma esta expresión:

p *a = "a" 

y lo traduce a algo como esto:

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

Así que la primera cosa que sucede es que a se asigna a "a", y luego el resultado de la asignación expresión que es "a" se splatted y se envía a p. Dado que el comportamiento predeterminado de p cuando se envían varios argumentos es solo iterar e imprimir cada uno, solo verá aparecer "a".

En resumen, sigue una orden de evaluación "asignar y marcar". Entonces, a se asigna a "a" antes de que se salte la cadena.

Cuando usted no tiene una llamada de función, sin embargo, se interpreta como algo parecido a esto:

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

Esto sigue un "splat luego asignar" orden de evaluación. Entonces a se asigna después de la cadena se salpica.

Se puede ver lo que está siendo recibido por una función yendo de esta manera:

def foo *args 
    puts args.inspect 
end 

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

la esperanza que esto aclare lo que está pasando!

En pocas palabras (gracias a Mark Reed):

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

derecho. Se trata de la precedencia. 'p * a =" a "' significa 'p (* (a =" a "))', no 'p (* a =" a ")'. –

+0

Sí, exactamente, lo edité para agregar un poco de una nota aclaratoria. – robbrit

Cuestiones relacionadas