How can I determine if something is a Perl 6 container?

I have no useful reason to know this, but I was wondering if I have a name like $x if it was a mutable thingy or just a name for something (an immutable thing), I'm not trying anything to do; this is curiosity.

I played with something like this:

 my @a = 'a', ('b', 'c' ); my @b = 'd', 'e', 'f', @a; my @ab = @a, @b, ( 1, 2 ); for @ab { put "name: {.^name} VAR: { .VAR.^name }"; when .VAR.can('FETCH') { put "Container: $_" } when .VAR.can('STORE') { put "Container: $_" } when Scalar { put "Scalar container: $_" } when Array { put "Array Container: $_" } default { put "Object: $_" } } 

I get:

 name: Array VAR: Scalar Array Container: abc name: Array VAR: Scalar Array Container: defabc name: List VAR: Scalar Object: 1 2 

I see that I can match Array type types, but I thought that checking that something could be FETCH or STORE would be a valid match.

+5
source share
1 answer

Not sure what you are asking here, but given your input, the result looks as expected.

A simplified example to illustrate:

 my (@a, @b, @c); my @ab = @a, @b, @c; for @ab { say "{.^name} contained in a {.VAR.^name}"; } 

which will output

 Array contained in a Scalar 

three times, regardless of the contents of @a , @b and @c .

Remember that in Perl6 there is no implicit smoothing, and the mutmility of an array (unrelated arrays) is realized by placing its elements in scalar containers.


Given the change in your question, perhaps the following code will again explain what happens:

 # make argument raw so binding won't mess with it sub info($_ is raw) { dd $_; put " value type: {.^name}"; put " VAR type: {.VAR.^name}"; put " can fetch: {so .VAR.can('FETCH')}"; put " can store: {so .VAR.can('STORE')}"; } my \values = 42, my $ = 42, [1, 2], (1, 2); info $_ for values; put "\n"; # put values in array, which wraps them in a scalar container info $_ for [values]; 

Note that only lists and arrays can STORE (but not FETCH ), while scalars cannot.

This may come as a surprise: first, we could expect all assignees to provide STORE .

Looking at the implementation, we see that for variables with the sigil @ and % we make a STORE call , but not so for variables with the sigil $ . If we rode along the rabbit hole, we would end up specifying a VM-level container , that is, as assigning scalar containers (or calling the STORE object's Proxy method).

+4
source

Source: https://habr.com/ru/post/1262639/


All Articles