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