Hash#delete currently returns nil if a given key is not found in the hash. It would be nice to have a way to check that the key was present in the hash. This can be accomplished with with a block, but it would be nice to have some sugar for this.
{a: 'a'}.delete(:b)# => nil{a: 'a'}.delete(:b){|key|raiseKeyError,"key not found #{key}"}# => KeyError (key not found: b)
Hash#delete is destructive, so appending ! doesn't seem making sense.
I'm as guilty of it as anyone, but as I understand ! does not mean destructive, but rather 'more dangerous', which I believe a possible exception qualifies for.
as I understand ! does not mean destructive, but rather
'more dangerous', which I believe a possible exception
qualifies for.
You may still have the issue of semantics.
For example, .fetch() semantic is different than .delete().
The way how I remember methods with a "!", even if this is
not the official one, is to think of the "!" as a "modify
in place" operation. If one thinks about it in this way
then .delete() already modifies in place so .delete!()
is not making a lot of sense. However had, please do not
think that I really mind either way - I am neutral on the
suggestion. Perhaps someone could mention it to matz
briefly in the next developer meeting since Ryan referred
to a comment from matz almost 10 years ago. :-)
As Matz clearly stated, even if a long time ago, bang is not strictly for mutating versions of methods. Note that there is Process#exit! (which is not a mutating version of Process#exit). Rails also has many bang methods which aren't mutating, in particular ActiveRecord#save!.
As Matz clearly stated, even if a long time ago, bang is not strictly for mutating versions of methods. Note that there is Process#exit! (which is not a mutating version of Process#exit). Rails also has many bang methods which aren't mutating, in particular ActiveRecord#save!.
It's clear that bang methods are not only for mutating versions of methods. However, it would be a bad idea to use a bang method in a context (such as delete) where it can be very easily mistaken as a mutating version (and by opposition, the non-bang method would be misunderstood as a non-mutating version). That's why I think it's a bad idea to use delete! in the sense proposed above.
it would be a bad idea to use a bang method in a context (such as delete) where it can be very easily mistaken as a mutating version (and by opposition, the non-bang method would be misunderstood as a non-mutating version).
I'm not sure that point holds in such a general way. E.g. I've never seen ActiveRecord::Base#destroy being mistaken for a non-destructive version of #destroy!.
In my opinion, the main reason why #delete! feels confusing is that there are already #delete and #delete! implementations in Ruby that differ by destructiveness, e.g. on String. That is an unfortunate inconsistency when compared to Hash#delete.
Maybe something like Hash#yank could be introduced as an alias for delete and #yank! as a whiny version. That could both serve the need stated by the OP and also undercut this existing inconsistency.