4

この質問に興味をそそられて、配列とメソッド呼び出しを使用した並列割り当てで少し遊んでみました。したがって、配列内の2つのメンバーを値で交換しようとするパラダイム的な例を次に示します。

deck = ['A', 'B', 'C']
#=> ["A", "B", "C"]
deck[deck.index("A")], deck[deck.index("B")] = deck[deck.index("B")], deck[deck.index("A")]
#=> ["B", "A"]
deck
#=> ["A", "B", "C"]

配列は変更されていません。しかし、引数の順序を変更すると、次のように機能します。

deck[deck.index("B")], deck[deck.index("A")] = deck[deck.index("A")], deck[deck.index("B")]
#=> ["A", "B"]
deck
#=> ["B", "A", "C"]

index割り当て内のメソッドを呼び出す順序に関係していると思いますが、はっきりとはわかりません。誰かが下の順序を説明できますか?最初の例ではメンバーが交換されず、2番目の例では交換されないのはなぜですか?

4

3 に答える 3

3

期待されています。それは ruby​​ が式を評価する方法から導かれる。

deck[deck.index("A")], deck[deck.index("B")] = deck[deck.index("B")], deck[deck.index("A")]

示す

deck[deck.index("A")], deck[deck.index("B")] = 'B', 'A'

注: ここでの文字列 'A' と 'B' は、説明のみを目的としています。ここでは、Ruby は新しい文字列オブジェクトを作成しません。本質的には次のとおりです。

deck[deck.index("A")] = 'B' -> deck[0] = 'B' (deck = ['B', 'B', 'C'])
deck[deck.index("B")] = 'A' -> deck[0] = 'A' (deck = ['A', 'B', 'C'])

Array#index は、最初の一致が見つかったときに戻ります。

今、

deck[deck.index("B")], deck[deck.index("A")] = deck[deck.index("A")], deck[deck.index("B")]
-> deck[deck.index("B")], deck[deck.index("A")] = 'A', 'B'
-> deck[deck.index("B")] = 'A' -> deck[1] = 'A' (deck = ['A', 'A', 'C'])
-> deck[deck.index("A")] = 'B' -> deck[0] = 'B' (deck = ['B', 'A', 'C'])
于 2010-11-15T09:55:59.673 に答える
1

M Rajesh は正しいですが、彼は実際にそれを解決するために考えなければなりませんでした。私はそれには怠惰です!

これは、何が起こったかを示す printf デバッグ方法です。

deck = ['A', 'B', 'C']
#=> ["A", "B", "C"]
deck[deck.index("A").tap {|index| 
  STDERR.puts "Result of indexing for #{"A".inspect} is #{index.inspect}"
  }], 
deck[deck.index("B").tap {|index| 
  STDERR.puts "Result of indexing for #{"B".inspect} is #{index.inspect}"
  }] = 
deck[deck.index("B")], deck[deck.index("A")]
# Result of indexing for "A" is 0
# Result of indexing for "B" is 0
#=> ["B", "A"]
deck
#=> ["A", "B", "C"]
于 2010-12-02T23:15:54.770 に答える
1

例として、配列を検索するために使用される機械化を比較し、正しいインデックスを見つけてから、ハッシュを使用してできることと値を交換します。

h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }

h['dog'], h['cat'] = h.values_at('cat', 'dog')

h #=> {"cat"=>"canine", "dog"=>"feline", "cow"=>"bovine"}

さて、Ruby に割り当て可能なvalues_at=Hash メソッドがあれば、さらにクリーンになる可能性があります。

h.values_at('dog', 'cat') = h.values_at('cat', 'dog')

しかし、残念ながら、そうではありません。ハッシュ スライシングは Perl の非常に強力なツールであり、Ruby について私が恋しく思うものです。

そして、はい、私は独自の assignable を追加できることを知っていvalues_at=ます。

于 2010-11-15T15:15:26.560 に答える