7

就我如何理解这个问题提供一些背景信息。

在字符串上使用 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"]
4

1 回答 1

9

非常有趣的问题!Ruby 采用以下表达式:

 p *a = "a"

并将其翻译成这样的:

 temp = (a = "a")
 p *temp

所以发生的第一件事就是a被分配给"a",然后分配表达式的结果"a"被喷溅并发送给p。由于p发送多个参数时的默认行为只是迭代并打印每个参数,因此您只会看到"a"出现。

简而言之,它遵循“先分配然后分解”的评估顺序。所以在字符串被喷溅之前a被分配给。"a"

但是,当您没有函数调用时,它被解释为如下所示:

# *a = "a" gets interpreted as:
temp = "a"
a = *temp

这遵循“先分配后分配”的评估顺序。所以在字符串被喷溅后被分配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")
于 2012-06-05T16:15:59.617 回答