There's the ff operator and the fff operator.

The ff operator allows both endpoints to match at the same time.
The fff operator doesn't.

On Sat, Jul 25, 2020 at 3:16 PM William Michels via perl6-users <
perl6-us...@perl.org> wrote:

> Hello,
>
> I'm trying to learn the "ff" (flipflop) infix operator, generally
> taking examples from the docs (below):
>
> https://docs.raku.org/routine/ff
>
> I tried adding in an "m:1st" adverb and an "m:2nd" adverb, but the
> output isn't what I expect with the "m:2nd" adverb (examples #3 and
> #5):
>
> say "\n1. ----";
> for <AB C D B E F> {
>     say $_ if /A/ ff /B/;  # OUTPUT: «AB␤»
> }
>

You should probably use the fff operator instead

    for <AB C D B E F> {
        say $_ if /A/ fff /B/;  # OUTPUT: «AB␤C␤D␤B␤»
    }


> say "\n2. ----";
> #mine
> for <AB C D B E F> {
>     say $_ if /A/ ff m:1st/B/;  # OUTPUT: «AB␤»
> }
>

I don't know why you would think that :1st would work that way.
:1st doesn't really do anything.
It makes it so that it matches at the first occurrence, which is the
default anyway.

    'ABcdeFB' ~~ m:1st/.B/; # 「AB」
    'ABcdeFB' ~~ m:2nd/.B/; # 「FB」

The /.B/ can match in two different places in the string, :1st makes it so
that it matches the first occurrence.
:2nd makes it match the second occurence.

At any rate it doesn't do anything special when used as part of a ff
operator.

If you wanted the 'B' to match at the first position, you need to indicate
that.
Generally you would use `^` for beginning of string.

    say $_ if /A/ ff /^B/; # OUTPUT: «AB␤C␤D␤B␤»


> say "\n3. ----";
> #mine
> for <AB C D B E F> {
>     say $_ if /A/ ff m:2nd/B/;  # OUTPUT: «AB␤C␤D␤B␤E␤F␤»
> }


None of those strings can match 'B' more than once, so m:2nd/B/ will always
fail.
Which means that the ff operator will not stop.


> say "\n4. ----";
> for <AB C D B E F> {
>     say $_ if /C/ ff *;    # OUTPUT: «C␤D␤B␤E␤F␤»
> }
>

Generally * matches everything.
In this case if it is on the right side of ff, it actually means don't stop.
(If it were on the left it would mean always start)

say "\n5. ----";
> #mine
> for <AB C D B E F> {
>     say $_ if m:2nd/B/ ff *;    # OUTPUT: blank
> }
>

Again there is nothing for :2nd to match, so it never does.

I'm wondering if I'm using the correct "flipflop" operator, since
> "ff", "ff^", "fff", and "fff^" are all provided in Raku.
>

I will say that fff is slightly easier to understand, but your real failure
to understand seems to be with :2nd.


Anyway it is intended to be more like:

    for < A B start C D E F end G H I J start K L M N O end P Q R S T U V W
X Y Z > {
      .say if "start" fff "end";
    }
    start
    C
    D
    E
    F
    end
    start
    K
    L
    M
    N
    O
    end

If you want to ignore the "start" you can use ^fff
If you want to ignore the "end" you can use fff^
If you want to ignore both use ^fff^

Same for ff  ( ^ff  ff^  ^ff^ )
And for .. ( ^..  ..^  ^..^ )

    for < A B start C D E F end G H I J start K L M N O end P Q R S T U V W
X Y Z > {
      .say if "start" ^fff^ "end";
    }
    C
    D
    E
    F
    K
    L
    M
    N
    O

In the above two cases ff and fff would behave identically.

The difference shines when the beginning marker can look like the end
marker.

    for 1..20 {
      .say if * %% 3 ff * %% 3
    }
    3 # matches both endpoints
    6 # ditto
    9
    12
    15
    18

    for 1..20 {
        .say if * %% 3 fff * %% 3
    }
    3 # matches beginning (left)
    4
    5
    6 # matches ending (right)
    9 # begin
    10
    11
    12 # end
    15 # begin
    16
    17
    18 # end

Reply via email to