Misc #11520
closedInconsistent behavior in Array#compact!
Description
I noticed that Array#compact! sometimes returns self and other times nil. This behavior was a bit confusing.
[].compact!
# => nil
[1].compact!
# => nil
[nil].compact!
# => []
[1, nil].compact!
# => [1]
I would prefer that Array#compact! either always returns nil, or always returns self.
Updated by 0x0dea (D.E. Akers) about 10 years ago
This behavior is consistent with many other "bang methods" which return nil if they might have mutated the receiver but didn't:
[
'foo'.downcase!,
'BAR'.upcase!,
'Baz'.capitalize!,
'foo'.strip!,
'bar'.lstrip!,
'baz'.rstrip!,
'foo'.sub!(/\d/, 'x'),
'bar'.gsub!(/\d/, 'x'),
'abc'.tr!('def', 'ghi'),
[1,2,3].compact!,
[1,2,3].flatten!,
[1,2,3].uniq!
].any? # => false
This idiom is a Good Thing because it provides you with greater information density than if these methods simply returned the mutated receiver, since that's something to which you already have a reference. In the common enough case that you want to know whether something changed, you can simply use the return value rather than storing a copy of the object and comparing it before and after (potential) mutation.
Updated by postmodern (Hal Brodigan) about 10 years ago
- Tracker changed from Bug to Misc
Ah, I was unaware that was the intention. I guess I should use .tap(&:compact!) instead. This issue can be closed.
Updated by nobu (Nobuyoshi Nakada) about 10 years ago
- Status changed from Open to Rejected