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))]
.
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.
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'));
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