Project

General

Profile

Misc #11520

Inconsistent behavior in Array#compact!

Added by postmodern (Hal Brodigan) almost 5 years ago. Updated almost 5 years ago.

Status:
Rejected
Priority:
Normal
Assignee:
-
[ruby-core:<unknown>]

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.

#1

Updated by 0x0dea (D.E. Akers) almost 5 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.

#2

Updated by postmodern (Hal Brodigan) almost 5 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.

#3

Updated by nobu (Nobuyoshi Nakada) almost 5 years ago

  • Status changed from Open to Rejected

Also available in: Atom PDF