# Enumerable works, Iterator doesn't, in 1.1.1

I was running old Rosetta Code examples with 1.1.1 and found this new error.

This code worked, at least upto 0.36.1, and compiles/run with 1.1.1.

``````struct PalindromicGapfuls
include Enumerable(UInt64)

@nn : Int32

def initialize(@digit : Int32)
@nn = @digit * 11                   # digit gapful divisor: 11, 22,...88, 99
end

def each
(2..).each do |power|
base    = 10_u64 ** (power >> 1)  # value of middle digit position: 10..
this_lo = base * @digit           # starting half for this digit: 10.. to  90..
next_lo = base * (@digit + 1)     # starting half for next digit: 20.. to 100..
this_lo.step(to: next_lo - 1, by: 10) do |front_half|   # d_10; d_20; d_30; ...
if power.odd?                   # for even number of total digits: ab..ba
front_half.upto(front_half + 9) do |upper_half|     # d_n0 to d_n9
palindrome_half = upper_half.to_s
palindrome = (palindrome_half + palindrome_half.reverse).to_u64
yield palindrome if palindrome % @nn == 0
end
else                            # for odd number of total digits: ab..m..ba
palindrome_half = (front_half // 10).to_s           # d_n
palindrome = (palindrome_half + "0" + palindrome_half.reverse).to_u64
# increase palindrome middle digit from ---0--- to ---9---
10.times do
yield palindrome if palindrome % @nn == 0
palindrome += base          # increase middle digit value
end
end
end
end
end
end

count, keep = 20, 20
puts "First 20 palindromic gapful numbers ending with:"
1.upto(9) { |digit| puts "#{digit} : #{PalindromicGapfuls.new(digit).first(count).last(keep)}" }
``````

This code worked, at least upto 0.36.1, but won’t compile with 1.1.1.

``````struct PalindromicGapfuls
include Iterator(UInt64)

@nn : Int32

def initialize(@digit : Int32)
@nn = @digit * 11                   # digit gapful divisor: 11, 22,...88, 99
end

def each
(2..).each do |power|
base    = 10_u64 ** (power >> 1)  # value of middle digit position: 10..
this_lo = base * @digit           # starting half for this digit: 10.. to  90..
next_lo = base * (@digit + 1)     # starting half for next digit: 20.. to 100..
this_lo.step(to: next_lo - 1, by: 10) do |front_half|   # d_10; d_20; d_30; ...
if power.odd?                   # for even number of total digits: ab..ba
front_half.upto(front_half + 9) do |upper_half|     # d_n0 to d_n9
palindrome_half = upper_half.to_s
palindrome = (palindrome_half + palindrome_half.reverse).to_u64
yield palindrome if palindrome % @nn == 0
end
else                            # for odd number of total digits: ab..m..ba
palindrome_half = (front_half // 10).to_s           # d_n
palindrome = (palindrome_half + "0" + palindrome_half.reverse).to_u64
# increase palindrome middle digit from ---0--- to ---9---
10.times do
yield palindrome if palindrome % @nn == 0
palindrome += base          # increase middle digit value
end
end
end
end
end
end

count, keep = 20, 20
puts "First 20 palindromic gapful numbers ending with:"
1.upto(9) { |digit| puts "#{digit} : #{PalindromicGapfuls.new(digit).skip(count-keep)}" }
``````

The error message is:

``````➜  rosettacode time crystal run palclass2.cr --release
Showing last frame. Use --error-trace for full trace.

In palclass2.cr:1:1

1 | struct PalindromicGapfuls
^
Error: abstract `def Iterator(T)#next()` must be implemented by PalindromicGapfuls
``````

The Docs for 1.1.1 show `Iterator` still have `next` and `skip` methods.

https://crystal-lang.org/api/1.1.1/Iterator.html

1 Like

This code worked, at least upto 0.36.1, but won’t compile with 1.1.1.

It didn’t compile with 0.36.1: Carcin

2 Likes

From the `Iterator` docs:

To implement an Iterator you need to define a #next method that must return the next element in the sequence or Iterator::Stop::INSTANCE, which signals the end of the sequence (you can invoke #stop inside an iterator as a shortcut).

i.e. `Iterator#next` is `abstract`: source

1 Like