'Getting "value without a container" error

Got this:

for $config.IO.slurp.lines <-> $l {
  $l .= trim;
  ...
}

Get this:

t/01-basic.rakutest ..3/5
Parameter '$l' expects a writable container (variable) as an argument,
but got '# karabiner config file' (Str) as a value without a container.
  in sub generate_file at...

I've read the docs on containers but it didn't shed any light on what I can do in this situation aside from maybe assigning $l to a scalar variable, which seems hacky. Is there a way I can containerize $l?



Solution 1:[1]

The issue is really that .lines does not produce containers. So with <->, you would bind to the value, rather than a container. There are several ways to solve this, by containerizing as you suggested:

for $config.IO.slurp.lines -> $l is copy {
    $l .= trim;
    ...
}

But that only makes sense if you want to do more changes to $l. If this is really just about trimming the line that you receive, you could do this on the fly:

for $config.IO.slurp.lines>>.trim -> $l {
    ...
}

Or, if you need to do more pre-processing $l, use a .map:

for $config.IO.slurp.lines.map({
    .trim.subst("foo","bar",:g)
}) -> $l {
    ...
}

Solution 2:[2]

Maybe below is what you want? Generally, you read a file via slurp you can comfortably handle its size, or you read a file via lines if you want input taken in lazily, one-line-at-a-time:

my $config = 'alphabet_one_letter_per_line.txt';

my $txt1 = $config.IO.slurp; 
$txt1.elems.say; #1
$txt1.print; #returns alphabet same as input

my $txt2 = $config.IO.lines;
$txt2.elems.say; #26
$txt2.join("\n").put; #returns alphabet same as input

Above, you get only 1 element when slurping, but 26 elements when reading lines. As you can see from the above code, there's no need to "...(assign) $l to a scalar variable..." because there's no need to create (temporary variable) $l.

You can store text in @txt arrays, and get the same number of elements as above. And you can just call routines on your stored text, as you have been doing (example below continues $txt2 example above):

$txt2.=map(*.uc);
say $txt2;

Sample Output:

(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)

[Note, this question seems to have triggered questions on the use of $txt2.=map(*.uc); versus $txt2.=uc;. My rule-of-thumb is simple: if the data structure I'm working on has more than one element, I map using * 'whatever-star' to address the routine call to each element].

https://docs.raku.org/

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2