2016-04-22 2 views
-1

Я пытаюсь получить очень удобный со всеми методами массива и перечислениями в Ruby, но я не понимаю, почему некоторые из них не мутируют, а другие делают. Например, есть разница между:Путаница мутации в Ruby Array?

def double(array) 
    array.map {|x| x * 2} 
end 

и

def double(array) 
    return array.map! {|x| x * 2} 
end 

Кроме того, когда я попытался позвонить

b.select{|x| x.even?} 

где Ь представляет собой массив целых чисел, она не изменилась , но

b = b.select{|x| x.even?} OR 
.delete_if 

действительно казалось мутировать его.

Является

a.each do |word| 
word.capitalize! 
end 

же, как

a.map do |word| 
word.capitalize 
end 

ответ

2

Как правило, ruby methods that end in ! will mutate the value they are called on и методы без возвращает мутантный копию.

Смотрите здесь документацию по map vs map! и capitalize vs capitalize!

Также отметим, что b = b.select{|x| x.even?} не мутирует список b, а скорее вызовом b.select создать совершенно новый список, и назначая этот список b. Обратите внимание на разницу:

В этом b тот же объект, только что изменил:

$ irb 
@irb(main):001:0> b = [1,2,3] 
=> [1, 2, 3] 
@irb(main):002:0> b.object_id 
=> 69853754998860 
@irb(main):003:0> b.select!{|x| x.even?} 
=> [2] 
@irb(main):004:0> b.object_id 
=> 69853754998860 

Но в этом, b теперь совершенно новый объект:

$ irb 
@irb(main):001:0> b = [1,2,3] 
=> [1, 2, 3] 
@irb(main):002:0> b.object_id 
=> 70171913541500 
@irb(main):003:0> b = b.select{|x| x.even?} 
=> [2] 
@irb(main):004:0> b.object_id 
=> 70171913502160 
+0

Typo: 'capitalze!' должен «капитализировать!». Кроме того, пример хорош, но выбор можно сделать еще более кратким: b.выберите (&: even?) –

+0

более лаконичный, да, но менее ясный; OP был смущен о характере разницы между двумя вызовами, называемыми подобными именами, бросая новую концепцию, подобную методу, прорабатывающему их, не собирается ничего делать, кроме как смущать их дальше. Спасибо за опечатку! – Hamms

1

есть разница между:

def double (array) array.map {| x | x * 2} end и

def двойной (массив) возврат массив.map! {| Х | x * 2} конец

Да. Первый возвращает новый массив. Второй изменяет исходный массив и возвращает его.

Является

a.each сделать | слово | word.capitalize! конец то же, что и

a.map do | word | word.capitalize end

№. Первый изменяет элементы в массиве и возвращает исходный массив. Второй возвращает новый массив, заполненный новыми строками.