Ожидается. Это следует из того, как 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'])
Массив # 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'])