Your results are what I would expect.

The hand crafted regex puts the exclusion logic in the *single*
regex that's applied by the *single* call to the `find` function.

The `any` value results in calling the `find` function *twice*,
with 'mothera' excluded one time, and 'camel' excluded the
second time.

Thus the result is an `any` junction, with two lists, one with
two files in it, the other with all three.

----

Consider a one arg function `function`, a one element junction `junction`,
and the following function call:

function junction

This will execute the function `function` once, using the single element
in the junction `junction`, then return a new junction of the same kind as
`junction` with one element, which will be the result of having called the
function `function` with the single element from the original junction
`junction` as the function `function`'s (only) argument.

Hopefully that makes sense, or hopefully the following example will.
Presume there is a single file in the current directory, `file.txt`. Thus:

say find: dir => '.', type => 'file', exclude => any rx/exe/ #
any("file.txt".IO)

----

You have provided more than one element for the `any` junction.

So `find` is called multiple times, once for each element of the `any`.

You have provided *two* elements in a junction used for the value
of one argument, namely `any( rx/<|w>mothera$/, rx/<|w>camel$/`.
Therefore `find` is called *twice*, once with each of the `rx`s, and
the result is an `any` containing the results from those two calls.

----

Hopefully the foregoing has made some sense, though you might
want to get up and go for a walk contemplating what it means for
something to be two things at once.

----

Assuming the foregoing has made sense, I'll drop in one other
wrinkle to consider. If you pass *multiple* arguments as junctions,
you have to take into account two aspects:

* Things multiply. If *two* function arguments are junctions, and
  each junction has, say, three elements, the function is set to be
  called *six* times.

* The combination has to follow precedence rules. I forget what
  they are, but the general scheme is that there are two levels
  and they do what's most natural. This will of course sound very
  odd so I'll leave it as a thing to explore if you explore this. :)

 --
love, raiph


On Fri, May 21, 2021 at 12:53 AM Joseph Brenner <doom...@gmail.com> wrote:
>
> The documentation for File::Find says that the exclude argument
> is applied via a smart-match, so I thought that I could use a
> junction, like so:
>
>    use File::Find
>    my @files = find( dir => $loc, type => 'file', exclude => any(
> @exclude_pats ) );
>
> But instead of getting an array of file names (either strings or
> IO objects would be fine), that returns an any junction of IO
> objects, built-up from a peculiar set of hits.
>
> Does that make sense to anyone?
>
> Here's some code that demos the problem:
>
> use v6;
> use File::Find;
>
> ## create some files to find
> my $loc = "/tmp/monster_island";
> mkdir( $loc );
> chdir( $loc );
> my @monsters = < godzilla mothera rhodan >;
> for @monsters -> $name {
>     $name.IO.spurt("The $name attacks!");
> }
>
> ## without exclude, we find all 3 files
> my @files_all = find( dir => $loc, type => 'file' );
> say @files_all.elems;     # 3
>
> ## with a handcrafted regex we find only 2, skipping mothera as expected
> my @files_trimmed = find( dir => $loc, type => 'file', exclude =>
> rx/<|w>[mothera|camel]$/ );
> say @files_trimmed.elems; # 2
>
> ## Trying to do the same with an any junction doesn't work:
> my @exclude = ( rx/<|w>mothera$/, rx/<|w>camel$/ );
> my @files = find( dir => $loc, type => 'file', exclude => any(@exclude) );
> say @files;
> # [any(("/home/doom/tmp/monster_island/godzilla".IO
> "/home/doom/tmp/monster_island/rhodan".IO),
> ("/home/doom/tmp/monster_island/godzilla".IO
> "/home/doom/tmp/monster_island/mothera".IO
> "/home/doom/tmp/monster_island/rhodan".IO))]
> ##
> ## (1) we end up with a single "any" junction in the first element
> ## (2) there are five hits, two redundant rhodan and godzillas, plus
> one mothera slips through (?)
>
> ## but note that this works:
> for @monsters {
>     .say unless $_ ~~ any(@exclude)
> }
> # godzilla
> # rhodan
>
>
>
> raku --version
> Welcome to 𝐑𝐚𝐤𝐮𝐝𝐨™ v2020.10.
> Implementing the 𝐑𝐚𝐤𝐮™ programming language v6.d.
> Built on MoarVM version 2020.10.

Reply via email to