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
end
Pushing 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
end
Collecting 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
end
Using 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
end
Output of running the code
10
13
23
all: [10, 13, 23]
1
1
2
3
5
8
In 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.