[Feature Proposal] with_iteration core extension to Enumerator

I’ve found the PartialIteration objects to be really helpful, and I’ve wished I could use them more easily in other loops.

My proposal is two-part: extract PartialIteration out of ActionView and into ActiveSupport as a more generic Iteration object (implementation can stay the same, just a new less View-specific name).

And then a core extension to Enumerator like this:

def with_iteration
  iteration = ActionView::PartialIteration.new(size)
  with_object(iteration) do |*args|
    yield *args
    iteration.iterate!
  end
end

And then for an example use:

- 5.times.with_iteration do |_, iteration|
  - unless iteration.last?
    .timeline-bar
  .timeline-element
    - # ...

I would be happy to put together a PR, but before I went through the trouble I thought I would see if there was any interest.

@willcosgrove Interesting idea, I didn’t know about PartialIteration!

One thing I thought of was what this code would look like just using existing facilities?

What I’m trying to say is what is the value proposition here?

Well, in the case of my contrived example, it wouldn’t be too useful since 5.times is pretty obvious how many times the loop will run. But if you had a collection of unknown size then the difference would be something like this:

Before

- collection_size = collection_of_unknown_size.size
- collection_of_unknown_size.each.with_index do |obj, index|
  - last = index == collection_size - 1
  - unless last
    .timeline-bar
  .timeline-element

After:

- collection_of_unknown_size.each.with_iteration do |obj, iteration|
  - unless iteration.last?
    .timeline-bar
  .timeline-element
1 Like

I see, thank you for explaining!

This use case seems reasonable enough to me, though not having done the homework of looking at alternatives that might already exist. It might also be worth going through the issue tracker to see if someone hasn’t already proposed this idea as a ticket or PR.