def generator_for(handle, args = {}, &block)
if handle.is_a?(Hash)
raise ArgumentError, "only specify one attr => value pair at a time" unless handle.keys.length == 1
gen_data = handle
handle = gen_data.keys.first
args = gen_data[handle]
end
raise ArgumentError, "an attribute name must be specified" unless handle = handle.to_sym
unless args.is_a?(Hash)
unless block
retval = args
block = lambda { retval }
end
args = {}
end
if args[:start]
block ||= lambda { |prev| prev.succ }
end
if args[:method]
h = { :method => args[:method].to_sym }
h[:start] = args[:start] if args[:start]
record_generator_for(handle, h)
elsif args[:class]
raise ArgumentError, "generator class [#{args[:class].name}] does not have a :next method" unless args[:class].respond_to?(:next)
record_generator_for(handle, :class => args[:class])
elsif block
raise ArgumentError, "generator block must take an optional single argument" unless (-1..1).include?(block.arity)
h = { :block => block }
h[:start] = args[:start] if args[:start]
record_generator_for(handle, h)
else
raise ArgumentError, "a block, :class generator, :method generator, or value must be specified to generator_for"
end
end