Search code examples
regexraku

Error while compiling regex function, why am I getting this issue?


My RAKU Code:

sub comments {
    if ($DEBUG) { say "<filtering comments>\n"; }
    my @filteredtitles = ();

    # This loops through each track
    for @tracks -> $title {

        ##########################
        # LAB 1 TASK 2           #
        ##########################
        ## Add regex substitutions to remove superflous comments and all that follows them
        ## Assign to $_ with smartmatcher (~~)
        ##########################
        $_ = $title;

        if ($_) ~~ s:g:mrx/ .*<?[\(^.*]> / {

        # Repeat for the other symbols

        ########################## End Task 2

        # Add the edited $title to the new array of titles
            @filteredtitles.push: $_;
        }
    }
        # Updates @tracks
        return @filteredtitles;
}

Result when compiling: Error Compiling! Placeholder variable '@_' may not be used here because the surrounding block doesn't take a signature.

Is there something obvious that I am missing? Any help is appreciated.


Solution

  • So, in contrast with @raiph's answer, here's what I have:

    my @tracks = <Foo Ba(r B^az>.map: { S:g / <[\(^]> // };
    

    Just that. Nothing else. Let's dissect it, from the inside out:

    This part: / <[\(^]> / is a regular expression that will match one character, as long as it is an open parenthesis (represented by the \() or a caret (^). When they go inside the angle brackets/square brackets combo, it means that is an Enumerated character class.

    Then, the: S introduces the non-destructive substitution, i.e., a quoting construct that will make regex-based substitutions over the topic variable $_ but will not modify it, just return its value with the modifications requested. In the code above, S:g brings the adverb :g or :global (see the global adverb in the adverbs section of the documentation) to play, meaning (in the case of the substitution) "please make as many as possible of this substitution" and the final / marks the end of the substitution text, and as it is adjacent to the second /, that means that

    S:g / <[\(^]> //
    

    means "please return the contents of $_, but modified in such a way that all its characters matching the regex <[\(^]> are deleted (substituted for the empty string)"

    At this point, I should emphasize that regular expressions in Raku are really powerful, and that reading the entire page (and probably the best practices and gotchas page too) is a good idea.

    Next, the: .map method, documented here, will be applied to any Iterable (List, Array and all their alikes) and will return a sequence based on each element of the Iterable, altered by a Code passed to it. So, something like:

    @x.map({ S:g / foo /bar/ })
    

    essencially means "please return a Sequence of every item on @x, modified by substituting any appearance of the substring foo for bar" (nothing will be altered on @x). A nice place to start to learn about sequences and iterables would be here.

    Finally, my one-liner

    my @tracks = <Foo Ba(r B^az>.map: { S:g / <[\(^]> // };
    

    can be translated as:

    I have a List with three string elements

    Foo
    Ba(r
    B^az
    

    (This would be a placeholder for your "list of titles"). Take that list and generate a second one, that contains every element on it, but with all instances of the chars "open parenthesis" and "caret" removed.

    Ah, and store the result in the variable @tracks (that has my scope)