2016-09-05 44 views
1

我有以下的陣列和方法:如果把感嘆號時方法鏈接

array = ["1", 0, "a", ""] 
array.reject(&:blank?).map(&:to_i).reject{|i| i == 0} 

如果我想保存利用感嘆號發生的變化,例如.map!(&:to_i),該標記應放在每種方法之後還是其他地方 - 在哪裏?

+2

解釋標記不是方法行爲的修飾符,它是方法名稱的一部分。 –

+0

這是如何改變我的問題的? –

+0

「在相同的地方」 – Ven

回答

4

感嘆號不是修飾符。

array.reject!(&:blank?).map!(&:to_i).reject!{|i| i == 0} 

但是,這段代碼是微妙的錯誤。來自reject!文檔:

如果未做任何更改,則返回nil。

哎呀!這可能會打破你的整個鏈條。相反,你應該使用delete_if,它總是返回數組。

array.delete_if(&:blank?).map!(&:to_i).delete_if{|i| i == 0} 

是的,它是有點麻煩,沒有爆炸,但它並就地修改。從文檔:

每次調用塊時都會立即更改數組,而不是在迭代結束後更改。

+0

爆炸並不一定添加在改變接收器的方法上,但通常在方法上做一些有潛在危險的事情。每次存在爆炸方法時,還應該有一種非爆炸方法,應該更安全。也就是說,這是其中一項尚未完全接受的公約。 –

+0

我認爲,因爲'delete_if'只是返回數組(真的在MRI源中)的'reject!',它應該有一個聲音:)。 – Ven

+0

@Ven,讀者可能會錯誤地推斷您的評論「delete_if」和「reject!」是等同的。如你所知,當沒有改變時,'delete_if'返回數組,而'reject!'返回'nil'。當然有許多方法可以修改接收器沒有爆炸的方法。我們應該寫'arr <<! 3'? –