2007-09-11

Simple higher order methods

Sometimes there's an itch that you just have to scratch. One of them hit me today, luckily I already had the matching scratch ready. My itch was, that while Ruby has that very nice module Enumerator, it only works with classes that provide a .each method. So you can have enum.map { ... }, which operates on each. But what if you have a class that can iterate over various things? E.g. a String could iterate over bytes, chars, words or lines. A directory could iterate over files, directories or all entries.
My solution to the problem: Iterator.
class Iterator
include Enumerable

class Iteration
def initialize(&block)
@block = block
end
def yield(*args)
@block.call(*args)
end
end

def initialize(&iterator)
@iterator = iterator
end

def each(&block)
@iterator.call(Iteration.new(&block))
end
end

With that you can enable a method to return an Iterator with a single statement, which in turn allows you to do things like: dir.entries.select { ... }, where dir.entries returns an Iterator.
Example use:
def each_custom
if block_given? then
@custom.each { |element| yield(element) }
else
Iterator.new { |iter| @custom.each { |element| iter.yield(element) } }
end
end

1 comment:

joshua said...
This comment has been removed by a blog administrator.