Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return the values in a junction as an array?

Define a junction my $j = 1 | 2 | 3 | 4 | 5, now I want to get an array of its value [1 2 3 4 5], how should I implement this?

I tried $j.values but Perl6 gave me the whole junction as an element: [any((1), (2), (3), (4), (5))].

like image 352
hwding Avatar asked Apr 23 '17 07:04

hwding


2 Answers

This is intentional, as far as I know.

Imagine $j containing a Junction of hashes: then $j.values would be a junction of Seq's, not the hashes themselves.

If you want the array of a junction, then maybe you should start from an array, and build a junction out of that:

my @a = 1,2,3,4,5;
my $j = any(@a);

If you really want to go the Junction -> Array way, you could, but it would involve using nqp, and that's something I would not recommend in userland code.

like image 62
Elizabeth Mattijsen Avatar answered Nov 10 '22 07:11

Elizabeth Mattijsen


As Håkon Hægland already pointed out, this is not something you're supposed to do:

Junctions are meant to be used as matchers in boolean context; introspection of junctions is not supported. If you feel the urge to introspect a junction, use a Set or a related type instead.

 -- docs.perl6.org/type/Junction

However, it is possible.

First, you can use authothreading (ie the automatic evaluation of each branch of a junction when passed to a function that expects an argument of type Any):

sub unjunc(Junction $j) {
    gather -> Any $_ { .take }.($j);
}

Second, you can poke into the guts and manually extract the values:

sub unjunc(Junction $j) {
    multi extract(Any $_) { .take }
    multi extract(Junction $_) {
        use nqp;
        my $list := nqp::getattr($_, Junction, '$!storage');
        my int $elems = nqp::elems($list);
        loop (my int $i = 0; $i < $elems; $i = $i + 1) {
            extract nqp::atpos($list, $i);
        }
    }
    gather extract $j;
}

If your junction is non-recursive (ie does not contain other junctions you want to flatten), the latter approach can be simplified:

my $j := 1|2|3;
say nqp::p6bindattrinvres(nqp::create(List), List, '$!reified',
    nqp::getattr($j, Junction, '$!storage'));
like image 6
Christoph Avatar answered Nov 10 '22 07:11

Christoph