Enumerable Magic – Boolean Methods

Learning over 50 methods in Ruby's Enumerable module can be a little daunting. It doesn't help that the official docs (which are awesome, by the way) sort the methods alphabetically, not by how they might be used. So for this tutorial, we'll start by looking at just those methods with a boolean (true or false) outcome. All of the source code for the following examples can be found on github:

https://github.com:bellmyer/rubycuts/enumerables

First, you should know that all examples here and in other Enumerable tutorials on this site will use one common set of example classes. A PetInventory class, which manages a collection of Pet objects, a file that contains a list of "pokey things", and a LogData class which iterates through Heroku log files in a RAM-friendly way.

all?

The all? method takes an enumerable collection and tests whether the given condition is true for every item in the collection. It returns true only if every element meets the condition.

Pet Inventory

The PetInventory class keeps track of how many pets our imaginary pet store has in stock at any given time. We also track the number of legs of each animal, in case somebody comes in not knowing what pet they want, but knowing how many legs it should have. Here's our initial pet inventory:

pet legs # in stock
dog 4 100
cat 4 50
fish 0 1000
scorpion 8 1
beetle 6 10,000
monkey 2 2
rock 0 0

Now, some code:

# view full source at https://github.com/rubycuts/enumerables/blob/master/lib/pet_inventory.rb

inventory = PetInventory.new

# do all pets have legs?
inventory.all?{|pet| pet.legs > 0}    #=> false

# are all pets in stock?
inventory.all?(&:in_stock?)    #=> false

# all pets have a name? 
inventory.all?{|pet| !pet.name.nil?}    #=> true

# if list is empty, is everything true? 
[].all?{|pet| pet.legs > 1000}    #=> true

Let's walk through these examples. Do all pets have legs? No, fish and rocks don't pass the legs > 0 test. Are all pets in stock? No, we're out of pet rocks. Do all pets have a name? Yes, no pet names are nil.

This last example is something I found interesting while playing with this method. If your list is empty, what does the all?

method return? By default, it returns true because no items failed the comparison test. Technically, no items passed either, which is a bit confusing, but I guess the authors picked the default that would work as you expect most of the time.

any?

The all? method takes an enumerable collection and tests whether the given condition is true for every item in the collection. It returns true only if every element meets the condition. Pet Inventory The PetInventory class keeps track of how many pets our imaginary pet store has in stock at any given time. We also track the number of legs of each animal, in case somebody comes in not knowing what pet they want, but knowing how many legs it should have. Here's our initial pet inventory:
petlegs# in stock
dog4100
cat450
fish01000
scorpion81
beetle610,000
monkey22
rock00
Now, some code:
# view full source at https://github.com/rubycuts/enumerables/blob/master/lib/pet_inventory.rb

inventory = PetInventory.new

# do all pets have legs?
inventory.all?{|pet| pet.legs > 0}    #=> false

# are all pets in stock?
inventory.all?(&:in_stock?)    #=> false

# all pets have a name? 
inventory.all?{|pet| !pet.name.nil?}    #=> true

# if list is empty, is everything true? 
[].all?{|pet| pet.legs > 1000}    #=> true
Let's walk through these examples. Do all pets have legs? No, fish and rocks don't pass the legs > 0 test. Are all pets in stock? No, we're out of pet rocks. Do all pets have a name? Yes, no pet names are nil. This last example is something I found interesting while playing with this method. If your list is empty, what does the all? method return? By default, it returns true because no items failed the comparison test. Technically, no items passed either, which is a bit confusing, but I guess the authors picked the default that would work as you expect most of the time.
Posted in Enumerable, Ruby, Tutorials and tagged , , .

Leave a Reply

Your email address will not be published. Required fields are marked *