This code works:
(3,6...66).contains( 9|21 ).say # OUTPUT: «any(True, True)»
And returns a Junction
. It's also tested, but not documented.
The problem is I can't find its implementation anywhere. The Str code, which is also called from Cool, never returns a Junction (it does not take a Junction, either). There are no other methods contain
in source.
Since it's autothreaded, it's probably specially defined somewhere. I have no idea where, though. Any help?
For example, your body has nerve junctions — the places where your nerves come together. You may go swimming at the junction of two rivers. Junction can also refer to something that connects things, like a junction you use to connect electrical cords.
A junction, when discussed in the context of transport, is a location where traffic can change between different routes, directions, or sometimes modes, of travel.
It also means that the streets or railway lines meet at a point. The junction is related to roads, canals, and rail. It also means two things are joined together which are in motion like nerve junction present in the body.
TL;DR Junction autothreading is handled by a single central mechanism. I have a go at explaining it below.
(The body of your question starts with you falling into a trap, one I think you documented a year or two back. It seems pretty irrelevant to what you're really asking but I cover that too.)
Where is contains( Junction) defined? ... The problem is I can't find [the Junctional] implementation anywhere. ... Since it's autothreaded, it's probably specially defined somewhere.
Yes. There's a generic mechanism that automatically applies autothreading to all P6 routines (methods, operators etc.) that don't have signatures that explicitly control what happens with Junction
arguments.
Only a tiny handful of built in routines have these explicit Junction
handling signatures -- print
is perhaps the most notable. The same is true of user defined routines.
.contains
does not have any special handling. So it is handled automatically by the generic mechanism.
Perhaps the section The magic of Junctions
of my answer to an earlier SO Filtering elements matching two regexes will be helpful as a high level description of the low level details that follow below. Just substitute your 9|21
for the foo & bar
in that SO, and your .contains
for the grep
, and it hopefully makes sense.
I'll focus on methods. Other routines are handled in a similar fashion.
method AUTOTHREAD
does the work for full P6 methods.
This is setup in this code that sets up handling for both nqp and full P6 code.
The above linked P6 setup code in turn calls setup_junction_fallback.
When a method call occurs in a user's program, it involves calling find_method
(modulo cache hits as explained in the comment above that code; note that the use of the word "fallback" in that comment is about a cache miss -- which is technically unrelated to the other fallback mechanisms evident in this code we're spelunking thru).
The bit of code near the end of this find_method
handles (non-cache-miss) fallbacks.
Which arrives at find_method_fallback
which starts off with the actual junction handling stuff.
This code works:
(3,6...66).contains( 9|21 ).say # OUTPUT: «any(True, True)»
It "works" to the degree this does too:
(3,6...66).contains( 2 | '9 1' ).say # OUTPUT: «any(True, True)»
See Lists become strings, so beware .contains()
and/or discussion of the underlying issues such as pmichaud's comment.
Routines like print
, put
, infix ~
, and .contains
are string routines. That means they coerce their arguments to Str
. By default the .Str
coercion of a listy value is its elements separated by spaces:
put 3,6...18; # 3 6 9 12 15 18
put (3,6...18).contains: '9 1'; # True
It's also tested
Presumably you mean the two tests with a *.contains
argument passed to classify
:
my $m := @l.classify: *.contains: any 'a'..'f';
my $s := classify *.contains( any 'a'..'f'), @l;
Routines like classify
are list routines. While some list routines do a single operation on their list argument/invocant, eg push
, most of them, including classify
, iterate over their list doing something with/to each element within the list.
Given a sequence invocant/argument, classify
will iterate it and pass each element to the test, in this case a *.contains
.
The latter will then coerce individual elements to Str
. This is a fundamental difference compared to your example which coerces a sequence to Str
in one go.
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