Translation of Ruby Code

I tried to use the Iterator module for this, but I’m missing something.
I assumed you had to make these iterators, but what’s the correct way to do this in Crystal?

squares  = Enumerator.new{ |y| (0..).each{ |n| y << 2**n}}
squares5 = Enumerator.new{ |y| (0..).each{ |n| y << 2**n * 5}}
 
pyth_quad = Enumerator.new do |y|
  n = squares.next
  m = squares5.next
  loop do
    if n < m
      y << n
      n = squares.next
    else
      y << m
      m = squares5.next
    end
  end
end

# this takes less than a millisecond
puts pyth_quad.take_while{ |n| n <= 1000000000}.join(" ")

This is what I came up with:

squares = (0..).each.map { |n| 2_i64**n }
squares5 = (0..).each.map { |n| 2_i64**n * 5 }

n = squares.next.as(Int)
m = squares5.next.as(Int)
pyth_quad = Iterator.of do
  if n < m
    value = n
    n = squares.next.as(Int)
  else
    value = m
    m = squares5.next.as(Int)
  end
  value
end

puts pyth_quad.take_while { |n| n <= 1000000000 }.join(" ")

Thank @asterite, as always.
The only thing I changed was the 2_i64 to 2_u64.

I got about 65-70% right, trying to following the examples in the docs.
I didn’t have the .map on the ends of (0..).each or the .as(Int) on the end of next, or moved m/n = squares/5... outside pyth_quad, or the .of on the end of Iterator.

I’m going to study it more, with the docs, to really understand what/why is going on.

FYI, here are time comparisons with different Ruby versions.
For Ruby ran as: $ time ruby pythquads.rb
For Crystal, compiled as: $ crystal build pythquads.cr --release
Ran as: $ time ./pythquads

Ruby 3.0.2              0.063 secs  
Ruby 2.7.4              0.057 secs
Truffleruby 21.2.0.1    0.037 secs
Crystal 1.1.1           0.007 secs
Crystal 1.2.1           0.002 secs

Ideally, the library or the compiler should be smarter about iterators that never finish, but that’s not the case right now. That’s why you need those as(Int) , because the return value of next could be Iterator::Stop.

I tried. To improve that but couldn’t. I’ll open an issue and see if someone can figure this out, or if it’s even worth it.