Unless I'm missing something, there is no bug here. Here's how each example works:
for $fh.lines -> $line { ... } The .lines method is only called once, and returns a lazy sequence of lines (represented as a Seq object). The `for` loop then iterates this sequence. for $fh.read(1024) -> $byte { ... } The .read method is only called once, and returns a binary buffer (represented as a Buf object). The `for` loop then iterates this buffer. It so happens that iterating a Buf iterates over its bytes, each represented as a number. while $fh.read(1024) -> $block { ... } The .read method is called repeatedly, once for each iteration of the while loop. Each iteration gets a Buf object. The while loop stops when `read` returns an empty Buf (which evaluates to False in boolean context).