perl6 "P6opaque, Str" vs simple "Str" types
Asked Answered
Z

1

8

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?

Zagreb answered 14/7, 2019 at 20:9 Comment(3)
I cannot make it fail. What did you enter at the prompt to make it fail?Partnership
Thank you very much Hakon Haegland. I use @a[0] in "tail(@a[0])" and that is the place it failed. I cannot make it fail either from REPL. There is nothing special in my code in feeding the elements of @a to $somelist.tail(@a[0]).Zagreb
Hi lisprogtor. "There is nothing special in my code in feeding the elements of @a to $somelist.tail(@a[0])". There's clearly something that's special. My guess is you've written int as a type somewhere instead of Int. Beyond that I doubt any of us will be able to help unless you post code and input data that together exhibit the problem. (Not the code/data you currently have if it's hundreds of lines long but a simplified version, preferably 5 lines or so and definitely no more than 50 lines, that produces the problem for you at least some times.)Aufmann
A
7

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.

You can only assign an integer to an integer variable

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.

Finding 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.

Red herring or LTA?

“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.

Aufmann answered 14/7, 2019 at 22:31 Comment(3)
Hi raiph, thank you very much for your detailed explanations. I always learn a great deal from you !!! I searched my codes where the variables are passed, and I don't see any static types. I basically just want to cut a list into various sizes according to input: my @a=prompt("foo: ").words; for @a -> $x { say (1,2,3,4,5).tail($x); }; I end up mapping user inputs to Int: (prompt("foo: ").words.map: {$_.Int}); Unfortunately, I am unable to reproduce the error from REPL, which is somewhat frustrating. I am still searching for source of the bug. I will find it in time. Thank you again raiph !!!Zagreb
@Zagreb If you can reproduce it at all, please save the code, the whole program, in a gist, and add a comment linking to it. Forget what I wrote about a minimum, anything that reproduces the problem will be wonderful. I promise I will appreciate it and dig into it. TIA if you have time. :)Aufmann
Thanks raiph ! I will try. Thanks !Zagreb

© 2022 - 2024 — McMap. All rights reserved.