Feature: more customizable sequences aka Arrays, Ranges and Stuff #339

wants to merge 1 commit into


None yet

2 participants


Hi, I needed this feature for a gem I am developing, so I was guessing why not trying to code it :-)
This feature allows to pass an Array, a Range or just an Enumerator (every kind of it) an treat it as a sequence.
I purposely did not try to monkey-patch any sort of class, or instance. Moreover, I preferred to avoid any error handling for the StopIteration error class, in that I suppose users looking for a custom enumerator are intentionally expecting an end. Otherwise they would build another kind of Enumerator, such as this: (0..10).cycle.

Thanks in advance to consider my pull request, and my best regards.


thoughtbot, inc. member

I'm going to hold off on merging this. We explain in our documentation that as long as whatever you pass responds to #next, it'll work fine - this means developers wanting to handle arrays or ranges can call to_enum (which returns an object responding to next) to accomplish this task.

The other thing to take into consideration is that if you call next too many times on some of your examples, it'll raise a StopIteration exception; that should be up to the developer to handle (either to restart from the beginning or let the exception bubble).


Hi Joshua, I tried to simplify the life when it comes to enumerators so I thought to call to_enum inside the Sequence#next.
Anyways, if you put an Enumerator using your example above, the first @value of the Sequence instance will be the Enumerator object instead of a value. Said so the part in the Sequence#next i committed could be considered.


thoughtbot, inc. member

@ricogallo I just added support for enumerators: 7b38221 You'll still have to call #to_enum on arrays (also note that ActiveSupport breaks Range#step and returns an array, so you'd have to do (0..10).step(2).to_enum) but it's a very simple solution that should solve most (if not all) issues! Thanks!


@joshuaclayton thanks to you! Actually without factory_girl in my every day work I would be lost :)

I notice the commit's message is longer than usual by far.. I guess Linus is somehow involved :)

thoughtbot, inc. member

@ricogallo Glad to hear how it's helped you! As for the commit messages, I've been known to get a bit long-winded in some of my commit messages - usually so I remember why I solved a problem in a certain way, or outline what's actually happening (or in this case, why something does or doesn't work). 😄

@danielfrey danielfrey pushed a commit to garaio/factory_girl that referenced this pull request May 15, 2012
@joshuaclayton joshuaclayton Sequences support Enumerators
This introduces an EnumeratorAdapter so everything coming in looks like
an Enumerator. It doesn't use the adapter if the #peek method exists on
the object.

This allows for sequences like:

    sequence(:cities, %w[Boston Atlanta Detroit Seattle].cycle)

This also makes it easier to cycle through arrays and ranges, since they
can be converted to Enumerators rather easily.

    sequence(:month, (1..12).to_enum)
    sequence(:month, %w[foo bar baz].to_enum)

This doesn't handle when calling Range#step out of the box, because
Ruby returns an Enumerator but ActiveSupport 3.x returns an array,
meaning #to_enum still needs to be called.

Closes #339, #378
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment