If you assign an undefined value to an array, it will contain that undefined value, which complicates using loops if you don't want to iterate over undefined values:
my @bar = 1, 2, Any;
for @bar -> $baz {
put $baz;
}
This gives the following output, including a warning for the undefined values:
1 2 Use of uninitialized value $baz of type Any in string context. Methods .^name, .perl, .gist, or .say can be used to stringify it to something meaningful. in block at for.p6 line 4
I know that I can deal with this explicitly in a number of way, for example:
for @bar -> $baz {
next unless $baz; # Skip this iteration
put $baz;
}
for @bar.grep: *.defined { # Just iterate over the defined values
put $baz;
}
# Reassign @bar to only contain defined values
@bar.=grep(*.defined);
for @bar -> $baz {
put $baz;
}
But, isn't there a more idiomatic way to avoid @foo
receiving undefined values or to avoid iterating over undefined values?
For the time being, when assigning to an array, I'm going to be using the following defined-flat
function to avoid these situations:
multi defined-flat (@array) {
return @array.grep(*.defined).flat;
}
# Return single defined element (or empty list for single undefined value)
multi defined-flat ($element) {
return $element // ();
}
You also can try to use map
to solve the problem:
my @a = [0, 1, 2, 3, Any].map({ $_ if $_.defined });
Or with race
to enable multi-threads:
my @a = [0, 1, 2, 3, Any].race.map({ $_ if $_.defined });
Or >>.
:
my @a = [0, 1, 2, 3, Any]>>.&({ $_ if $_.defined });
I prefer the last one :p
You could use duckmap
my @bar = 1, 2, Any;
@bar.duckmap: -> Mu:D $baz {
put $baz;
}
duckmap -> Mu:D $baz {
put $baz;
}, @bar;
# the “:” makes this a method call
duckmap @bar: -> Mu:D $baz {
put $baz;
}
Also sometimes handy is the with statement, which both topicalizes and tests for definedness:
my @bar = 1, 2, Any;
for @bar -> $baz {
put $_ with $baz
}
Or:
my @bar = 1, 2, Any;
for @bar {
with $_ -> $baz {
put $baz;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With