阵列爆炸方法的行为

时间:2010-09-18 13:39:15

标签: ruby arrays

如果没有进行任何更改,Array方法的某些爆炸版本就像compact!reject!flatten!uniq!返回nil

[1,[2]].flatten!
# => [1, 2]
[1,2].flatten!
# => nil
[1,[2]].flatten
# => [1, 2]
[1,2].flatten
# => [1, 2]

[1,2,nil].compact!
# => [1, 2]
[1,2].compact!
# => nil
[1,2,nil].compact
# => [1, 2]
[1,2].compact
# => [1, 2]

如果他们这样做,就必须有理由。任何想法可能是什么?

2 个答案:

答案 0 :(得分:18)

bang(!)方法会修改当前对象,但如果每个the documentation没有受影响的元素,它们会返回nil。如果您因为某种原因需要执行某些操作(如果您修改了相关数组),这将非常有用。

if array.flatten!
  puts "Oh yeah... flattened that array!"
end

答案 1 :(得分:4)

  

我总是留下印象   bang版本的Array方法是   只是他们的方式不同   修改对象。

这里的问题可能是这种印象不是真正的印象:according to David A. Black !并不意味着该方法会更改其接收方; !表示此方法是其他等效方法的“危险”版本,其名称与!相同。

现在危险有多种形式(强调我的):

  

有时你会得到不止一种   甚至在一声巨响中“危险”   方法。拿String#gsub!。这个   方法更改其接收器:

str = "David" 
str.gsub!(/$/, " Black")
str                        # David Black
     

它也不同于gsub(非爆炸)   如果字符串没有改变,   gsub返回未更改的副本   字符串但gsub!返回nil:

str.gsub(/xyz/, "blah")    # David Black
str.gsub!(/xyz/, "blah")   # nil
str                        # David Black
     

!在gsub!中为您提供了一个单挑:   它警告你危险,这意味着   在你使用这个方法之前,你   应该弄清楚它是怎么回事   行为。(简单的“ri String#gsub!”   应该这样做。)

这种“单挑”语义也适用于Array的爆炸方法。