From: Robert Dober Date: 2007-06-08T04:41:32+09:00 Subject: Re: What about a 'series' type? On 6/7/07, Robert Klemme wrote: > On 07.06.2007 16:52, Peter Marsh wrote: > >> primes = Series.new(Starting_value,Some_block_to_define_serires) > > > > Just wanted to be a bit clearer about this, the second argument is a > > block which can generate nth term in a series. This would probally take > > a while for primes, but if it were recursive then it would be easier... > > IMHO for a series it would be more natural to let the block calculate > a[n+1] from a[n] wouldn't it? Of course, for Fibonacci this would only > work if you allow for multiple arguments. > > Something like > > #!ruby > class Serial > include Enumerable > > def initialize(*init, &f) > @init = init > @f = f > end > > def each(&b) > a = b.arity > current = @init > loop do > b[*current[0 ... a]] > current = Array(@f[*current]) > end > self > end > end > > s1 = Serial.new 0 do |x| x+1 end > s1.each {|x| p x; break if x > 10} > > puts > > s2 = Serial.new 0,1 do |a,b| [b,a+b] end > s2.each {|x| p x; break if x > 40} > Robert I hope you do not mind my fantasy about/over/at??? your theme. class Serial include Enumerable def initialize(*init, &f) @init = init @f = f @arity = f.arity end def get_some( some = nil, &b) @current = @init.dup if some && b.nil? then (0...some).inject([]) do |acc,| compute_next acc << @current.first end else a = b.arity loop do break if some && ( some -= 1 ) < 0 b[*@current.first( a )] compute_next end self end end private def compute_next @current += Array( @f[*@current] ) @current = @current.last @arity end end s1 = Serial.new 0 do |x| x+1 end s1.get_some {|x| p x; break if x > 10} puts "-"*42 puts s1.get_some(6) puts "-"*42 f = Serial.new 1, 1 do |x, y| x + y end f.get_some(6){ |x,| puts x } puts "-"*42 a = Serial.new 1, 1, 1 do |x, y, z| x + y + z end puts a.get_some(6) Cheers Robert -- You see things; and you say Why? But I dream things that never were; and I say Why not? -- George Bernard Shaw