From: Brian Candler Date: 2004-10-08T01:51:34+09:00 Subject: Re: Range behavior (Re: [RCR] New [] Semantics) On Fri, Oct 08, 2004 at 01:19:21AM +0900, trans. (T. Onoma) wrote: > - The Ranges #succ can be overridden as either a proc or a an object. > If an object, then each step is simply determined by the addition > of that object, i.e. self + #succ. If that succ object is a > Numeric, then the range is a numeric range and can gain the > speed advantages of the faster modulo #member? code. I think more generally, if you provide a proc, then you don't need to stipulate addition here; the proc could be { |x| x+1 }, or it could be { |x| x*2 } class DiscreteRange4 include Enumerable def initialize(seed, count, succmeth=:succ) @seed = seed @count = count @succmeth = succmeth end def each val = @seed if @succmeth.respond_to?(:call) @count.times do yield val val = @succmeth.call(val) end else @count.times do yield val val = val.send(@succmeth) end end end end DiscreteRange4.new(10,5).each { |x| puts x } DiscreteRange4.new(10,5,proc {|x| x=x-1}).each { |x| puts x } (leaving aside that we might want to replace count with an end value or an end test proc) So, we've made an iterator generator. I'm not sure how useful this is, because in these cases it's probably simpler just to write your own iterator: x = 10 5.times do puts x x = x-1 end Especially where the range is given by a length, and so you can use n.times { block } to run it. Regards, Brian.