Re: increasing counter whithin loop?
- From: mental@xxxxxxxxx
- Date: Thu, 8 Dec 2005 10:14:11 +0900
Quoting Patrick Gundlach <clr9.10.randomuser@xxxxxxxxxxxxxxx>:
> OK, then it makes sense that one cannot manipulate counter. But
> IMO it is not intuitive (POLS ;-)) that the counter in the
> for-loop can't be changed.
Maybe think of it like foreach in TCL [ foreach i $things { ... } ],
or the one for in Javascript [ for (var i in things) { ... } ]
rather than for in C.
As a rule, I think Ruby's going to be extremely counterintuitive
whenever you expect C-like behavior.
> Yes, sure, but now it is getting ugly again. I am not looking for
> any way to work, but to find a readable, beautiful and ruby-like
> piece of code.
That will probably require thinking about it from a different angle.
The "skip the next (future) element based on the current one" is an
inherently messy concept.
Notching up the counter in a C-style loop is a _concise_ way to do
that, but it's still not particularly easy to reason about if your
loop is nontrivial.
It seems like the cleaner and more Ruby-esque solutions offered so
far involve attacking it from the other end -- "skip the current
element based on the previous one". It's clearer to remember
things from the past than it is to reach forward into the future.
Along those lines (this is basically Trans' suggestion):
a = %w(a b c d e)
prev = nil
a.each do |elt|
puts elt unless prev == "b"
prev = elt
end
Now, we'll imagine for the moment that Ruby has C-like for loops:
a = %w(a b c d e)
for ( i = 0 ; i < a.size ; i += 1 )
puts a[i]
i += 1 if a[i] == "b"
end
I don't know. I'm not sure I would find the C version clearer if I
weren't a grizzled old C veteran.
Out of curiousity, do you think either of these would be clearer?
a.each_with_prev do |elt, prev|
next if prev == "b"
puts elt
end
or
a.each_with_prev do |elt, prev|
puts elt unless prev == "b"
end
Don't forget that you're allowed to define convenience methods if
that would clarify things elsewhere:
module Enumerable
def each_with_prev( initial=nil )
prev = initial
each do |elt|
begin
yield elt, prev
ensure # in case of 'next'
prev = elt
end
end
end
end
A lot of Ruby's clarity comes not from being able to write things
clearly in the "raw" language, but from being able to easily
customize the language for your needs.
-mental
.
- Follow-Ups:
- Re: increasing counter whithin loop?
- From: Patrick Gundlach
- Re: increasing counter whithin loop?
- From: Ryan Leavengood
- Re: increasing counter whithin loop?
- References:
- increasing counter whithin loop?
- From: Patrick Gundlach
- Re: increasing counter whithin loop?
- From: Patrick Gundlach
- Re: increasing counter whithin loop?
- From: mental
- Re: increasing counter whithin loop?
- From: Kevin Brown
- Re: increasing counter whithin loop?
- From: Patrick Gundlach
- Re: increasing counter whithin loop?
- From: mental
- Re: increasing counter whithin loop?
- From: Patrick Gundlach
- increasing counter whithin loop?
- Prev by Date: Re: code execution from file?
- Next by Date: Re: RubyScript
- Previous by thread: Re: increasing counter whithin loop?
- Next by thread: Re: increasing counter whithin loop?
- Index(es):
Relevant Pages
|