# Author:: Tyler Rick # Copyright:: Copyright (c) 2007 QualitySmith, Inc. # License:: Ruby License # Submit to Facets?:: Yes! require 'enumerator' module Enumerable # The core Enumerable module provides the following enumerator methods; # * enum_cons() # * enum_slice() # * enum_with_index() # but for some reason they didn't provide a generic enum() method for the cases they didn't think of! # # +enum+ lets you turn *any* iterator into a general-purpose Enumerator, which, according to the RDocs, is # "A class which provides a method `each' to be used as an Enumerable object." # # This lets you turn any 'each'-type iterator (each_byte, each_line, ...) into a 'map'-type iterator, or into an array, etc. # # So if an object responds to :each_line but not to :map_lines or :lines, you could just do: # object.enum(:each_line).map { block } # object.enum(:each_line).to_a # object.enum(:each_line).min # object.enum(:each_line).grep /pattern/ # # If no iterator is specified, :each is assumed: # object.enum.map { block } # # More examples: # Dir.new('.').enum.to_a # #=> ['file1', 'file2'] # # "abc".enum(:each_byte).map{|byte| byte.chr.upcase} # #=> ["A", "B", "C"] # def enum(iterator = :each) Enumerable::Enumerator.new(self, iterator) end # Old version, which I don't think was accurate since enum requires obj to be Enumerable as a prerequisite!: # # Lets you add the methods available to Enumerables to any object that responds to :each (or any other iterator). # +enum+ returns a general-purpose Enumerator, which, according to the RDocs, is "A class which provides a method `each' to be used as an Enumerable object." # # This lets you use 'map'-type iterator, for example, on an object that only provides an 'each'-type iterator. # So if an object only responds to :each, but you want to send it :map, you could just do: end # _____ _ # |_ _|__ ___| |_ # | |/ _ \/ __| __| # | | __/\__ \ |_ # |_|\___||___/\__| # =begin test require 'test/unit' class TheTest < Test::Unit::TestCase def test_1 # @options.enum(:each).map { |key, value| # values = [value].flatten # key + # (values.empty? ? " #{flatten.join(' ')}" : '') # }.join(' ') # Yes we could use the built-in Array#map method, but...not every class that provides iterators (each, ...) provides a map(). assert_equal ['A', 'B', 'C'], ['a', 'b', 'c'].enum(:each).map {|v| v.upcase} end def test_2 assert Dir.new('.').enum.to_a.size > 0 end end =end