给我一点关于我如何理解这个问题的背景知识。
对字符串使用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”打印结果会更改分配给a的值?
进一步论证
class String
def to_ary
[self.upcase!]
end
end
p *a = "a" #=> "a"
p a #=> "a"
*b = "b"
p b #=> ["B"]
最佳答案
很有趣的问题!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”的求值顺序。因此
a
在字符串被飞溅之后被赋值。您可以通过如下方式查看函数接收的内容:
def foo *args
puts args.inspect
end
foo *a = "a" # outputs ["a"]
a # outputs "a"
希望这能澄清一切!
简而言之(感谢马克·里德):
p *a = "a" # interpreted as: p(*(a = "a"))
*a = "a" # interpreted as: a = *("a")