Feature #7994
closedMake iterators pass an implicit named parameter `iteration` to the executed block
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
Updated by alexeymuranov (Alexey Muranov) almost 12 years 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
- [page_ranges_before, page_ranges_after].each do |page_ranges|
- 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
Updated by regularfry (Alex Young) almost 12 years 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/7994Author: 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
Updated by alexeymuranov (Alexey Muranov) almost 12 years 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?
Updated by matz (Yukihiro Matsumoto) almost 12 years 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.
Updated by alexeymuranov (Alexey Muranov) almost 12 years 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
Updated by marcandre (Marc-Andre Lafortune) almost 12 years 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?
Updated by alexeymuranov (Alexey Muranov) almost 12 years 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.
Updated by marcandre (Marc-Andre Lafortune) almost 12 years 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!
Updated by alexeymuranov (Alexey Muranov) almost 12 years ago
Ok, i see.