I’m writing a distributed system simulator in Ruby and had a need to verify that an array contained only integer process ID’s, and no elements of any other type. Using Ruby’s Enumerable#inject function, this is a wonderfully quick one-liner.
>> a = [1,2,3] => [1, 2, 3] >> a.inject(true) do |result, element| result && element.is_a?(Fixnum) end => true >> b = [1,"Hi",3] => [1, "Hi", 3] >> b.inject(true) do |result, element| result && element.is_a?(Fixnum) end => false
Edit: After I posted this, Robert Riemann pointed out that Enumerable#inject iterates over the entire array even if the first value in the array is not an integer. This is easily confirmed as follows:
>> a.inject(true) do |result,element| puts "Next element"; result && element.is_a?(Fixnum) end Next element Next element Next element => false
So, inject is not what we’re looking for in this case. Later, Martin Vidner offered a solution using Enumerable#all?:
>> a = [1,2,3] => [1, 2, 3] >> a.all? do |e| e.is_a?(Fixnum) end => true >> b = [1,"Hi",3] => [1, "Hi", 3] >> b.all? do |e| e.is_a?(Fixnum) end => false
Using all?, we see that processing stops after a non-integral value is encountered:
>> b = [1,"Hi",3] => [1, "Hi", 3] >> b.all? do |e| puts "Next element"; e.is_a?(Fixnum) end Next element Next element
Thanks to both Robert and Martin for pointing out the problem in my original solution.