ruby - Why is the splat/unary operator changing the assigned value a when p is called before *a = ""? -


to give little context around how understand problem.

using splat collect on string sends :to_a or :to_ary string

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

so thinking redefining :to_ary method i'm after.

class string   def to_ary     ["to_a"]   end end  p *a = "a" #=> "a" p        #=> "a"  *b = "b" p b        #=> ["to_a"] 

now confuses me no end.

printing result *a = "a" changes value assigned a?

to demonstrate further

class string   def to_ary     [self.upcase!]   end end  p *a = "a" #=> "a" p        #=> "a"  *b = "b" p b        #=> ["b"] 

very interesting question! ruby takes expression:

 p *a = "a" 

and translates this:

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

so first thing happens a gets assigned "a", , result of assignment expression "a" gets splatted , sent p. since p's default behaviour when sent multiple arguments iterate on , print each one, see "a" appear.

in short, follows "assign splat" order of evaluation. a gets assigned "a" before string gets splatted.

when don't have function call however, interpreted this:

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

this follows "splat assign" order of evaluation. a gets assigned after string gets splatted.

you can see what's being received function going this:

def foo *args   puts args.inspect end  foo *a = "a"    # outputs ["a"]               # outputs "a" 

hope clears what's going on!

in short (thanks mark reed):

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

Comments

Popular posts from this blog

django - How can I change user group without delete record -

java - Need to add SOAP security token -

java - EclipseLink JPA Object is not a known entity type -