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
Post a Comment