7

私が問題をどのように理解しているかについて少し説明します。

文字列でsplatcollectを使用すると、: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"]
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"

これで何が起こっているのかが明らかになることを願っています!

要するに(マークリードのおかげで):

p *a = "a"    # interpreted as: p(*(a = "a"))
*a = "a"      # interpreted as: a = *("a")
于 2012-06-05T16:15:59.617 に答える