Hmm.
I had a look at class String and class Array what they do.
First Array:
array = [1,2,3] # => [1, 2, 3]
array.compact! # => nil
Next class String - it has no .compact but perhaps we can use
.delete! which may be somewhat similar:
string = 'abc' # => "abc"
string.delete! 'd' # => nil
So I assume that the nil returned there may be consistent behaviour. Probably
by nature of the assumption of what is returned, modification in place on
the same object, or a modification what would return a new object.
However had I do agree that, either way, the documentation could be more explicit.
No harm in mentioning that the hash.compact! variant will return nil, which is
what it is presently doing (for an empty hash).
For non-empty hashes as result, it indeed returns the remaining hash, which is
a bit strange, since it may also return a nil ... so people have to check whether
they really have a hash there or just an il:
hash = { foo: nil, bar: 'yes' } # => {:foo=>nil, :bar=>"yes"}
hash.compact! # => {:bar=>"yes"}
I do however had also agree that the behaviour may be a bit unexpected... so perhaps
the documentation can be fixed either way and then we can ask whether the behaviour
is the way it should be - but I actually assume that it may be just a documentation
problem.