Christopher Bottoms
Christopher Bottoms

Reputation: 11158

Can I introspect a variable to directly discover what subset it was declared with?

Is there a way to introspect a variable to directly find out what subset it was declared with? Here I create a subset, but introspection points me to its base type:

> subset Prime of Int where .is-prime
(Prime)
> my Prime $x = 23
23
> $x.WHICH
Int|23

I know it has to store the information somewhere, because if I try to reassign a value that doesn't match the subset, it fails:

> $x = 24
Type check failed in assignment to $x; expected Prime but got Int (24)
in block <unit> at <unknown file> line 1

I tried searching through the code, but I quickly get down into files like container.c and perl6_ops.c where the C code makes my eyes glaze over. I thought that X::TypeCheck::Assignment might help (see core/Exception.pm), but it's not clear to me where the expected value comes from. (see also this commit)

I feel like I'm missing something obvious.

I can check that something matches a subset, but that doesn't tell me if it were declared with a particular subset:

> my Int $y = 43;
43
> $y ~~ Prime;
True

I'm using Rakudo Star 2017.01


Inspired by a Zoffix's use of subsets in a recent post.

Upvotes: 4

Views: 122

Answers (1)

Elizabeth Mattijsen
Elizabeth Mattijsen

Reputation: 26924

The value that you stored in $x is an Int. It is acceptable to the container (which you typed to Prime) because Prime is a subtype of Int.

So what you're interested in, is not the value in the container, but the type of the container. To get at the container, Perl 6 has the .VAR method. And that has an .of method to get at the type:

$ 6 'subset Prime of Int where .is-prime; my Prime $x; dd $x.VAR.of'
Prime

Upvotes: 4

Related Questions