Sandwich Scheduling: a look at Ruby's Array cycle method
- By Tim Ash
- 28 September
How Ruby can help you schedule your sandwiches
You won't believe what happens when all the animals run away from the zoo.
In Ruby, Arrays are ordered lists of objects. For example:
array_of_integers = [1, 2, 3]
array_of_strings = ["This", "That", "The Other"]
array_of_all_sorts = ["fish", :bicycle, 3.14, 17]
empty_array = []
There are a couple of array methods that are often useful, .any?
and .all?
. .any?
will return true if the supplied block returns true for at least one item in the array. For example:
[1, 2, 3, 4].any? { |n| n.odd? }
will return true
, while
[2, 4, 6, 8].any? { |n| n.odd? }
will return false
.
Similarly, .all?
will return true
if the supplied block does not return false
for any item in the array:
[1, 2, 3, 4].all? { |n| n < 10 }
will return true
, while
[1, 2, 3, 4].all? { |n| n.even? }
will return false
.
However, it may not be obvious (it wasn’t to me) what .any?
and .all?
return when called on an empty array.
[].any? { |n| n.even? }
will always return false
, as it is not true that the supplied block returns true
for at least one item in the array, because there are zero items in the array. Which brings us to the question of what is returned when we call .all?
on an empty array.
[].all? { |n| n.even? }
will always return true
, because the supplied block does not return false
for any of the items in the array, as there are no items in an empty array. Which is logical, after a fashion, but can lead us to some odd places. Imagine we’ve got some code to keep track of the animals in a zoo - to keep things simple, let’s say these animals consist of one lion, and one zebra.
$ animals_in_the_zoo = [:lion, :zebra]
=> [:lion, zebra]
We’ve no unicorns in the zoo, so when we ask if all the animals are unicorns, .all?
returns false
:
$ animals_in_the_zoo.all? { |animal| animal == :unicorn }
=> false
Now let’s say the lion escapes:
$ animals_in_the_zoo.delete(:lion) # the lion escapes!
We’re left with one zebra, and no unicorns, so .all?
still returns false.
$ animals_in_the_zoo.all? { |animal| animal == :unicorn } # returns false
=> false
Now the zebra escapes:
$ animals_in_the_zoo.delete(:zebra) # the zebra escapes, too!
But now .all?
behaves in what might appear to be an unexpected way:
$ animals_in_the_zoo.all? { |animal| animal == :unicorn }
=> true
Now that all the animals in the zoo have escaped, all you have left are unicorns! As we saw above, this is because the supplied block does not return false
for any of the items in the array (animals in the zoo), as there are no items in an empty array.
I’d love to hear your thoughts on Ruby arrays, and indeed, unicorns. Why not leave a comment below?
I’ve been asked more than once about which Ruby books I would recommend. Ruby coders of all levels will get a lot out of David Black’s The Well-Grounded Rubyist. It’s one Ruby book I keep coming back to.
How Ruby can help you schedule your sandwiches
Another way Ruby can help you keep track of your lockdown exercise routine
How Ruby can help you keep track of your lockdown exercise routine
How Ruby can help you mix the drinks and bust some moves at the charity ball
Home, home on the Range, where the Ewoks and the Wookies play
An example of Ruby metaprogramming, by way of juggling chainsaws.
We would love to hear from you so let's get in touch!