Error: expected argument #1 to 'Array(UInt128)#[]' to be Range(B, E), not (UInt8 | Nil) ### https://forum.crystal-lang.org/t/custom-prng-binary-output/5028

I am trying to capture STDIN bytes and record them in an array that consists of counters ( aka histogram ).

#!/usr/bin/crystal

a=Array(UInt128).new(256)

10.times do
char = STDIN.raw &.read_byte
a[char]+=1
end

but i get a compiler error:

Error: expected argument #1 to ‘Array(UInt128)#’ to be Range(B, E), not (UInt8 | Nil)

I am not sure how to solve this

a[char] cannot be a Range imho but surely ist UInt8 ( and possibly Nil).

Ah, I’m starting to think we should not show “expected argument…” if an argument matches partially.

Read the full error:

Overloads are:
 - Array(T)#[](start : Int, count : Int)
 - Array(T)#[](range : Range)
 - Indexable(T)#[](index : Int)

The char you are passing is UInt8 | NIl because read_byte can return nil.

But, yeah, the error message isn’t helpful.

so how can i use the char to adress the array index then ? ( it could be any value 0…255 )

Maybe something like…

10.times do
  char = (STDIN.raw &.read_byte) || break # Finish early if we get a Nil
  a[char]+=1
end

Or…

10.times do
  char = STDIN.raw &.read_byte
  if char
    a[char]+=1
  else
    break # or whatever
  end
end
2 Likes