The bang (!) methods do modify the current object in place, but they do return nil if there are no affected elements per the documentation. This is useful if, for whatever reason, you need to do something if you did modify the array in question.
if array.flatten!
puts "Oh yeah... flattened that array!"
end
Answer from Dave Pirotte on Stack OverflowHi all
I know how to use the bang (!) operator. I know why to use it. I've used it before but to help me understand it better does anyone have a really simple (useful/common pattern) example where one would be used?
I've looked online and can only find simple examples showing how to use it but it is used in a redundant way just to show how it works. I want a simple self-contained example of something where it must be used and 'the compiler isn't smart enough to figure out' as they say.
Thanks in advance
Videos
The bang (!) methods do modify the current object in place, but they do return nil if there are no affected elements per the documentation. This is useful if, for whatever reason, you need to do something if you did modify the array in question.
if array.flatten!
puts "Oh yeah... flattened that array!"
end
I was always under impression that bang version of
Arraymethods are only different in the way that they modify object in place.
Perhaps the problem here is that this impression is not really a correct one: according to David A. Black, ! does not mean that the method changes its receiver; ! means that this method is the "dangerous" version of an otherwise equivalent method, which has the same name minus the !.
Now danger takes many forms (emphasis mine):
Sometimes you get more than one kind of "danger" even within one bang method. Take
String#gsub!. This method changes its receiver:str = "David" str.gsub!(/$/, " Black") str # David BlackIt also differs from
gsub(non-bang) in that if the string does not change,gsubreturns a copy of the unchanged string butgsub!returns nil:str.gsub(/xyz/, "blah") # David Black str.gsub!(/xyz/, "blah") # nil str # David BlackThe ! in
gsub!gives you a heads-up: it warns you of danger, and that means that before you use the method, you should find out exactly how it behaves. (A simple "ri String#gsub!" should do it.)
This "heads-up" semantics also applies to the bang methods of Array.
Was hoping someone would have more insight on this. Array.shift() takes O(N) time to execute. I was wondering, with ECMA6, if this could be an alternative with O(1) time complexity:
var val, arr = [1, 2, 3]; [val, ...arr] = arr; //val = 1 and arr = [2, 3]
It's still O(n) because the implementation still has to copy all the items but one into a new array. It's really no different than using shift(). The same amount of copying occurs, it's just that the destination is a new array instead of the existing array.
There's no way to avoid O(n) behavior as long as you're using an array. Use a deque instead.
Pop() is faster than shift() as it cuts off the last item in the array rather than splicing out the first item and reindexing the array.
Queue.js is better still.