Home > Articles > Programming > Ruby

  • Print
  • + Share This
This chapter is from the book

This chapter is from the book

Creating Enumerable Classes

You may find that you need to make information in a given, custom data structure available to the rest of the world. In such a case, if the data structure that you have created to store arbitrary objects implements an #each method, the Enumerable mix-in will allow anyone who uses your class to access several traversal and searching methods, for free.

require 'enumerator'

class NumberStore
        include Enumerable

        attr_reader :neg_nums, :pos_nums

        def add foo_object
                if foo_object.respond_to? :to_i
                        foo_i = foo_object.to_i
                        if foo_i < 0
                                @neg_nums.push foo_i
                        else
                                @pos_nums.push foo_i
                        end
                else
                        raise "Not a number."
                end
        end

        def each
                @neg_nums.each { |i| yield i }
                @pos_nums.each { |i| yield i }
        end

        def initialize
                @neg_nums = []
                @pos_nums = []
        end
end

mystore = NumberStore.new
mystore.add 5
mystore.add 87
mystore.add(-92)
mystore.add(-1)

p mystore.neg_nums
p mystore.pos_nums

p mystore.grep -50..60

Produces:

[-92, -1]
[5, 87]
[-1, 5]

In the above contrived example, I have created a data structure called NumberStore which stores negative numbers in one list and positive numbers in another list. Because the #each method is implemented, methods like #find, #select, #map, and #grep become available. In the last line of the code sample I use the mixed-in method #grep to find numbers stored in mystore that are between 50 and 60.

  • + Share This
  • 🔖 Save To Your Account