"Brian Schroeder" <spam0504@bssoftware.de> schrieb im Newsbeitrag news:pan.2004.09.05.11.20.28.668820@bssoftware.de...
Hello everybody,
I've got a stylistic question. I know that "the ruby way" to implement
iterations is using .each and similar things, but sometimes I like to use
for i in 0...n
for j in i...n
do something with i and for
end
Thats nice.
But if I want to iterate downwards the only way I found is 10.downto(0) do
> i | end
That seems not as intuitive as the for notation. Especially if I want ruby
to teach algorithms to people who know how to read pseudo code, then I'd
like something like
for i in 10.downto 0
for i in 0.upto 10
I think this has been discussed before, but I'd like to now which style
you use, or if I've missed the solution.
regards,
Brian
PS: How is for implemented? Can I maybe teach Number.downto to return an
object that
   is used by for to iterate like an inverse range?
Even more straightforward: you can implement a range that supports both directions yourself plus arbitrary stepping like this:
class Rg
  include Enumerable
  def initialize(from, to, step = sign(to - from))
    raise ArgumentError, "Invalid step #{step}" if (to - from) * step <= 0
    @from, @to, @step = from, to, step
    @to += @step - ((@to - @from) % @step)
  end
  def each
    x = @from
    until x == @to
      yield x
      x += @step
    end
    self
  end
  def sign(x)
    case
      when x > 0
        1
      when x == 0
        0
      else
        -1
    end
  end
end
module Kernel
private
  def Rg(from, to, *step) Rg.new(from, to, *step) end
end
Then you can do this:
for i in Rg 0, 10, 2
  puts i
end
0
2
4
6
8
10
=> #<Rg:0x10186da0 @from=0, @step=2, @to=12>
for i in Rg( 0, -10, -3 )
  puts i
end
0
-3
-6
-9
=> #<Rg:0x101801a0 @from=0, @step=-3, @to=-12>
for i in Rg 0, -10
puts i
end
0
-1
-2
-3
-4
-5
-6
-7
-8
-9
-10
=> #<Rg:0x10199ce8 @step=-1, @to=-11, @from=0>
Kind regards
    robert