I have a large hash of arrays,
%qual<discordant>
(~approx. 13199 values like '88.23', '99.23', etc.
which ranges from 88-100, and are read in from text files,
and when I print %qual<discordant>.min
and %qual<discordant>.max
I can see the values are clearly wrong.
I can fix this by changing how the data is read in from the text files:
%qual{$type}.push: @line[5]
to
%qual{$type}.push: @line[5].Num
but this wasn't intuitive, this took me a few minutes to figure out why Raku/Perl6 was giving clearly incorrect answers at first. It would have been very easy to miss this error. In perl5, the default behavior would be to treat these strings like numbers anyway.
There should be some control statement to make this the default behavior, how can I do this?
The problem / feature is really that in Raku when you read lines from a file, they become strings (aka objects of type Str
). If you call .min
and .max
on an array of Str
objects, then string semantics will be used to determine whether something is bigger or smaller.
There are special values in Raku that act like values in Perl. In Raku these are called "allomorphs". They are Str
, but also Num
, or Rat
, or Int
, or Complex
.
The syntax for creating an appropriate allomorph for a string in $_
is << $_ >>
. So if you change the line that reads the words to:
my @line = $line.words.map: { << $_ >> }
then the values in @line
will either be Str
, or IntStr
or RatStr
. Which should make .min
and .max
work like you expect.
However, if you are sure that only the 5th element of @line
is going to be numeric, then it is probably more efficient to convert the Str
to a number before pushing to the array. A shorter syntax for that would be to prefix a +
:
%qual{$type}.push: +@line[5]
Although you might find that too line-noisy.
UPDATE: I had forgotten that there's actually a sub called val
that takes an Str
and creates an appropriate allomorph of it (or returns the original Str
). So the code for creating @line
could be written as:
my @line = $line.words>>.&val
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