给我一点关于我如何理解这个问题的背景知识。
对字符串使用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")

10-05 20:32
查看更多