提供一些关于我如何理解问题的背景信息。
在字符串上使用splat collect发送:to_a或:to_ary到字符串
class String
def method_missing method, *args, &block
p method #=> :to_ary
p args #=> []
p block #=> nil
end
end
*b = "b"
所以我认为重新定义:to_ary方法将是我追求的目标。
class String
def to_ary
["to_a"]
end
end
p *a = "a" #=> "a"
p a #=> "a"
*b = "b"
p b #=> ["to_a"]
现在这让我感到困惑。
打印* a =“a”的结果会更改分配给?
的值进一步证明
class String
def to_ary
[self.upcase!]
end
end
p *a = "a" #=> "a"
p a #=> "a"
*b = "b"
p b #=> ["B"]
答案 0 :(得分:9)
非常有趣的问题! Ruby接受这个表达式:
p *a = "a"
并将其翻译成以下内容:
temp = (a = "a")
p *temp
所以首先发生的事情是a
被分配到"a"
,然后分配表达式"a"
的结果会被摧毁,已发送至p
。由于p
发送多个参数时的默认行为只是迭代并打印每个参数,因此您只会看到"a"
出现。
简而言之,它遵循“分配然后splat”评估顺序。因此,在字符串被喷溅之前,a
会被分配到"a"
。
但是,如果没有函数调用,则会将其解释为:
# *a = "a" gets interpreted as:
temp = "a"
a = *temp
这是在“splat then assign”评估顺序之后。因此,在字符串被splatted后,a
被分配。
您可以通过以下方式查看函数收到的内容:
def foo *args
puts args.inspect
end
foo *a = "a" # outputs ["a"]
a # outputs "a"
希望这可以清除正在发生的事情!
简而言之(感谢Mark Reed):
p *a = "a" # interpreted as: p(*(a = "a"))
*a = "a" # interpreted as: a = *("a")