The reason it fails, is that:
my $test = $file.read: 8;
puts the Buf that is returned by $file.read into a Scalar variable, aka inside a container. And containerized is interpreted by for as itemized, to be considered a single item. So with:
.chr.say for $test;
you're calling the .chr method on the whole Buf, rather than on the individual elements.
There are a number of solutions to this:
- make sure there's no container:
my $test := $file.read: 8;
This makes sure there is no container by binding the Buf.
- make it look like an array
my @test := $file.read: 8;
Same as 1 basically, make the @test be an alias for the Buf. Note that this should also use binding, otherwise you'll get the same effect as you saw.
- make it work like an Iterable
.chr.say for @$test;
By prefixing the @ you're telling to iterate over it. This is basically syntactic sugar for the $test.list workaround you already found.
Re the $test.is-lazy.say, that is False for just about anything, e.g. 42.is-lazy.say; # False, so that doesn't tell you very much :-)