Previous Page
Next Page

8.13. Mapping and Grepping

Always use a block with a map and grep.

The map and grep builtins each have two valid syntaxes:

    map BLOCK LIST           grep BLOCK LIST
    map EXPR, LIST           grep EXPR, LIST

That is, the code that tells map how to transform a list, or tells grep how to filter it, can be specified either as a single expression or in a block.

But when the first argument to a map or grep is specified as an expression, it becomes harder to distinguish from the remaining arguments:

    print grep valid($_), @candidates;

    @args = map substr($_, 0, 1), @flags, @files, @options;

The block form makes the transform or filter stand out more clearly:


    print grep { valid($_) } @candidates;

    @args = map {substr $_, 0, 1} @flags, @files, @options;

Using a block also avoids mistakes like:

    @args = map substr $_, 0, 1, @flags, @files, @options;

Here the programmer seems to have thought that substr would somehow work out that it should consume only the first three arguments ($_, 0, 1), to magically produce an "extract the first character" expression that the map can then apply to the remaining arguments. Unfortunately, what happens instead is that the compiler notices that substr was given six arguments and complains:

    Too many arguments for substr at demo.pl line 42, near "@options;"

Using the block form instead:


    @args = map {substr $_, 0, 1} @flags, @files, @options;

makes the intent clearboth to the compiler and to subsequent readers.

More importantly, the expression forms of map and grep don't scale well as their transforms or filters become more complicated. If additional statements need to be added to a map or grep expression (for example, to inject a lexical variable, as shown in "List Processing Side Effects" in Chapter 6), that expression almost always has to be converted to a block. Starting out with a block reduces the amount of rewriting that's then required, and hence decreases the chances of new bugs being introduced.

    Previous Page
    Next Page