Deleting items from an array requires multiple passes to remove them all
That's you modifying underlying collection while iterating over it.
Basically, if collection changes in some way during iteration (becomes empty, gets prepended with a new element, etc), iterator doesn't have a lot of ways to handle it.
Try reject instead.
list.reject! {|item| item.name =~ /cat|dog|rat/i }
There is another way to do the same as reject!
with delete
:
list.delete_if { |item| item =~ /cat|dog|rat/i }