To give a little context around how I understand the problem.
Using splat collect on a string sends :to_a or :to_ary to the String
class String
def method_missing method, *args, &block
p method #=> :to_ary
p args #=> []
p block #=> nil
end
end
*b = "b"
So I was thinking that redefining the :to_ary method would be what I’m after.
class String
def to_ary
["to_a"]
end
end
p *a = "a" #=> "a"
p a #=> "a"
*b = "b"
p b #=> ["to_a"]
Now this confuses me to no end.
Printing the result from the *a = “a” changes the value assigned to a?
To demonstrate further
class String
def to_ary
[self.upcase!]
end
end
p *a = "a" #=> "a"
p a #=> "a"
*b = "b"
p b #=> ["B"]
Very interesting question! Ruby takes this expression:
and translates it to something like this:
So the first thing that happens is that
agets assigned to"a", and then the result of the assignment expression which is"a"gets splatted and sent top. Sincep‘s default behaviour when sent multiple arguments is just to iterate over and print each one, you only see"a"appear.In short, it follows a “assign then splat” order of evaluation. So
agets assigned to"a"before the string gets splatted.When you don’t have a function call however, it is interpreted as something like this:
This follows a “splat then assign” order of evaluation. So
agets assigned after the string gets splatted.You can see what’s being received by a function by going like this:
Hope this clears up what’s going on!
In short (thanks to Mark Reed):