Почему я не могу изменить значения массива в методе? - PullRequest
3 голосов
/ 11 мая 2011

В приведенном ниже фрагменте кода массив deck должен равняться [6,9,5,6,5,1,2], поскольку Ruby передает массивы по ссылке. После вызова метода значения колоды не меняются. Почему это так?

def count_cut!(deck)
  s1, s2 = deck[0, deck.last], deck[deck.last..-2]
  deck = s2 + s1 + [deck.last]
end

deck = [5, 1, 6, 9, 5, 6, 2]
count_cut!(deck)
p deck

Я использую Ruby 1.9.2-p180.

Ответы [ 4 ]

8 голосов
/ 11 мая 2011

Присвоение deck не изменяет массив, который был передан. Он рассматривается как локальная переменная в области определения функции. Вы можете позвонить deck.replace, если действительно хотите изменить его.

5 голосов
/ 11 мая 2011

Сделайте это Ruby: вместо изменения исходного массива верните измененный массив:

def count_cut(deck)
  s1, s2 = deck[0, deck.last], deck[deck.last..-2]
  s2 + s1 + [deck.last]
end

Затем вызывающая сторона присваивает возвращаемое значение deck:

deck = [5, 1, 6, 9, 5, 6, 2]
deck = count_cut(deck)
p deck

Но рассмотрите возможность инкапсуляции всего этого в классе колоды, особенно если колода имеет другое поведение:

class Deck

  def initialize(cards)
    @cards = cards
  end

  def count_cut!
    s1, s2 = @cards[0, @cards.last], @cards[@cards.last..-2]
    @cards = s2 + s1 + [@cards.last]
  end

end

deck = Deck.new [5, 1, 6, 9, 5, 6, 2]
deck.count_cut!
p deck
2 голосов
/ 11 мая 2011

. + Метод Array возвращает вам new Array. Используйте .unshift для изменения исходного объекта.

deck = [1,2,3,4,5]
p deck.object_id #some_number
deck = [6] + deck
p deck.object_id #another_number
deck.unshift([7])
p deck.object_id #unchanged 
1 голос
/ 11 мая 2011

Вы не изменяете массив, на который ссылается переменная deck, вы просто назначаете новый массив локальной переменной deck:

deck = s2 + s1 + [deck.last]

Приведенное выше создает новый массив, содержимое которого s2 + s1 + [deck.last], затем этот новый массив присваивается локальной переменной deck. Массив, на который изначально ссылалась deck, остается неизменным. Если вы хотите изменить массив, вам понадобится что-то вроде этого:

deck_last = deck.last
deck.clear
deck.push(*s2)
deck.push(*s1)
deck.push(deck_last)

или вы потеряете связь между локальной переменной deck и нелокальным массивом, на который она ссылается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...