Range Over Iterators in Ruby
Our example program demonstrates iteration over custom data structures and an infinite sequence generator. Here’s the full source code translated to Ruby.
Example
We start by defining the List class, which uses a linked list structure to hold elements.
class Element
attr_accessor :next, :val
def initialize(val)
@val = val
@next = nil
end
end
class List
def initialize
@head = nil
@tail = nil
end
def push(val)
if @tail.nil?
@head = Element.new(val)
@tail = @head
else
@tail.next = Element.new(val)
@tail = @tail.next
end
end
def all
Enumerator.new do |yielder|
e = @head
while e
yielder << e.val
e = e.next
end
end
end
endPushing elements into the list
Method push adds an element to the list, handling both the empty and non-empty cases.
list = List.new
list.push(10)
list.push(13)
list.push(23)Iterating over the list
We can iterate over the list using Ruby’s Enumerator.
list.all.each do |e|
puts e
endCollecting all elements
Ruby has built-in methods like to_a to collect values from an Enumerator.
all_elements = list.all.to_a
puts "all: #{all_elements.inspect}"Infinite sequence generator
Next, we define a generator for Fibonacci numbers. The fib_gen method yields Fibonacci numbers indefinitely.
def fib_gen
Enumerator.new do |yielder|
a, b = 1, 1
loop do
yielder << a
a, b = b, a + b
end
end
endUsing the Fibonacci generator
We can iterate over our Fibonacci generator and break under conditions we define.
fib_gen.each do |n|
break if n >= 10
puts n
endOutput of running the code
10
13
23
all: [10, 13, 23]
1
1
2
3
5
8In summary, we translated the example to Ruby, focusing on idiomatic use of classes, methods, and Ruby’s powerful enumerator-based iteration. This translation demonstrates handling of both finite and infinite sequences elegantly.