I was trying to obtain a list from user input doing my usual codes, but sometimes it fails unpredictably due to this error:
This type cannot unbox to a native integer: P6opaque, Str
The code line is
my @a = prompt("Enter list: ").words || (1,2,3);
It failed only if I enter only one number.
When is a Str converted to "P6opaque, Str" without user awareness? I cannot use +@a[0] or @a[0].Int to convert this "P6opaque, Str" to an Int. What am I missing here?
TL;DR The mention of P6Opaque
is a mostly a red herring. Some code is trying to assign a string to an int
. You'll need to coerce it to an Int
first. I know you've tried that. All that's left is to find out where it needs to be done. Hopefully this answer will guide us there.
It's an error to assign a string to an Int
or an int
:
my Int $a = '1'; # Type check failed ... expected Int but got Str
my int $a = '1'; # This type cannot unbox to a native integer: P6opaque, Str
The error on assigning to an Int
is caught by high level machinery which responds with a high level error message. For int
it's low level machinery which responds with a low level message. We'll take a closer look at this difference below, but it's a red herring as far as fixing your problem is concerned.
To fix this problem you'll need to find where a string is being assigned or bound to a variable with a native integer type constraint like int
and then coerce before the assignment with something like this:
my int $a = +'1' # Works
I know you've tried something like that. I don't know why it hasn't worked because you haven't yet shared the part of your code that's causing the problem.
There must be some use of a native integer that's either directly in your code (i.e. you explicitly specified a native integer type, an all lowercase type like int
, int32
, uint
etc.) or in some code your code uses.
So, search your code first.
If you still haven't found it, then please share enough of your code that we can reproduce the problem, preferably after reading StackOverflow's freshly Named/URLed page How to create a Minimal, Reproducible Example. TIA.
“P6opaque, Str” vs simple “Str” types
They're the same. P6opaque, Str
is a reference to exactly the same type as Str
.
When is a
Str
converted to "P6opaque, Str" without user awareness?
It isn't.
Quoting is repr
and native representations:
P6opaque
is the default representation used for all objects in Perl 6.
A representation is a set of rules for representing a type in a computer's memory.
Errors related to P6 objects are generally handled by the high level "front end" of the P6 language/compiler. High level error messages don't mention representations because most ordinary P6 objects have the same one (P6Opaque
) and even when they don't the representation still won't be relevant.
But here we're dealing with an error handled by MoarVM.
MoarVM's error messages don't mention the representation if it's deemed irrelevant. For example:
my int64 $a = 2⁶³
displays a MoarVM exception with an error message about the bigint
type whose representation is P6bigint
:
Cannot unbox 64 bit wide bigint into native integer
This error message doesn't mention the representation (P6bigint
).
But the MoarVM response to trying to put anything other than an integer into a native integer is a MoarVM exception which does mention the representation. For example, if you attempt to assign an Str
it's:
This type cannot unbox to a native integer: P6opaque, Str
If someone doesn't know about representations, this message is bit opaque aka LTA. But while removing the representation removes the confusion it also removes information that might be important:
This type cannot unbox to a native integer: Str
I'm not convinced that that is actually better and/or worthwhile but if you feel strongly about it, feel free to file a MoarVM bug about this with an LTA tag.
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