Skip to content

Instantly share code, notes, and snippets.

@fbacall
Created July 18, 2019 10:43
Show Gist options
  • Save fbacall/ae6f3bff338cd51801e83779209d572a to your computer and use it in GitHub Desktop.
Save fbacall/ae6f3bff338cd51801e83779209d572a to your computer and use it in GitHub Desktop.
Yielder & Enumerator pure Ruby example implementation
# Using standard library
fib = Enumerator.new do |y|
a = b = 1
loop do
y << a
a, b = b, a + b
end
end
p fib.take(10)
# => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
# Re-implemented
class FYielder
def initialize(&block)
@f = Fiber.new do
puts "Starting fiber"
block.call(self)
end
end
def <<(value)
puts "<< called"
Fiber.yield(value)
end
def get_val
puts "get_val called"
@f.resume
end
end
class FEnumerator
def initialize(&block)
@yielder = FYielder.new(&block)
end
def next
@yielder.get_val
end
def take(x)
x.times.map { self.next }
end
end
fib = FEnumerator.new do |y|
puts "block called"
a = b = 1
loop do
puts "inner loop"
y << a
a, b = b, a + b
end
end
p fib.take(10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment