Feature #7994

Make iterators pass an implicit named parameter `iteration` to the executed block

Added by Alexey Muranov about 1 year ago. Updated about 1 year ago.

[ruby-core:53072]
Status:Rejected
Priority:Normal
Assignee:-
Category:-
Target version:-

Description

=begin
I think it would be nice to be able to write something like this:

items.each do |item|
unless iteration.first?
# do something that is not applicable to the first iteration
end
# do whatever is to be done to all items
end
=end

History

#1 Updated by Alexey Muranov about 1 year ago

=begin
As a use case, i wanted to create a pagination navigation element on a web page in ((Haml)) template. What i ended up with looks redundant to me. With the suggested feature, i would be able to do:

%nav.pagination
- [pagerangesbefore, pagerangesafter].each do |pageranges|
- unless iteration.first?
%span.page.active
= active
page
- page_ranges.each do |range|
- unless iteration.first?
%span.ellipsis

- range.each do |page|
%button.page{ :type => :submit, :name => :page, :value => page }
= page

In other words, this would give an "imperative" solution to "Loop and a Half Problem".
=end

#2 Updated by Alex Young about 1 year ago

On 01/03/13 15:21, alexeymuranov (Alexey Muranov) wrote:

Issue #7994 has been reported by alexeymuranov (Alexey Muranov).

What advantages does this have over:

items.drop(1).each do |item|

or

items[1..-1].each do |item|

or to invert it:

items.first.tap do |item|

?

--
Alex


Feature #7994: Make iterators pass an implicit named parameter iteration to the executed block
https://bugs.ruby-lang.org/issues/7994

Author: alexeymuranov (Alexey Muranov)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:

=begin
I think it would be nice to be able to write something like this:

items.each do |item|
unless iteration.first?
# do something that is not applicable to the first iteration
end
# do whatever is to be done to all items
end
=end

#3 Updated by Alexey Muranov about 1 year ago

regularfry (Alex Young) wrote:

On 01/03/13 15:21, alexeymuranov (Alexey Muranov) wrote:

Issue #7994 has been reported by alexeymuranov (Alexey Muranov).

What advantages does this have over:

items.drop(1).each do |item|

or

items[1..-1].each do |item|

or to invert it:

items.first.tap do |item|

?

Sorry, i didn't understand, how do you plan to use this?

#4 Updated by Yukihiro Matsumoto about 1 year ago

  • Status changed from Open to Rejected

Nice idea.

But I reject the idea for Ruby for two reasons:

  • I personally don't like implicit parameters
  • That might cause incompatibility by conflicting with existing local variable name

Maybe good for a new language without existing set of programs.

Matz.

#5 Updated by Alexey Muranov about 1 year ago

=begin
Ok, then i make a last try: what about adding it in the end of parameter list as an optional parameter?

items.each do |item, iteration|
unless iteration.first?
# do something that is not applicable to the first iteration
end
# do whatever is to be done to all items
end
=end

#6 Updated by Marc-Andre Lafortune about 1 year ago

Please think about the number of incompatibilities this would bring... not all enumerables are sequences of single items.

Just use each_with_index and index.zero? instead of iteration.first?

#7 Updated by Alexey Muranov about 1 year ago

Marc-Andre, thanks for the idea, i did not realize that each_with_index works with all enumerables.

However i was hoping that something like unless iteration.first? could be some day optimized away by a compiler to not check on every iteration. I also do not see right away an incompatibility introduced by my second proposal (about the original one you are right).

Update: well, maybe there is no real advantage compared to each_with_index and index.zero?, i will use it.

#8 Updated by Marc-Andre Lafortune about 1 year ago

I also do not see right away an incompatibility introduced by my second proposal (about the original one you are right).

#before
1,2.each{|a, b| p a, b} # => 1, then 2
# after
1,2.each{|a, b| p a, b} # => [1, 2], then<#your iteration object>

BTW, all hashes would be affected like this!

#9 Updated by Alexey Muranov about 1 year ago

Ok, i see.

Also available in: Atom PDF