in reply to Re: Open Filehandle once (updated)
in thread Open Filehandle once

Hello thanos1983,

Please do not recommend File::Slurp. It's broken and wrong.

Also please do not recommend using map in void context. This is considered bad practice by many programmers since you are only making the call for its side-effects whilst throwing away its output.


The way forward always starts with a minimal test.

Replies are listed 'Best First'.
Re^3: Open Filehandle once
by kcott (Archbishop) on Aug 25, 2017 at 01:39 UTC
    "Also please do not recommend using map in void context."

    In general, I agree with this statement.

    "This is considered bad practice by many programmers since you are only making the call for its side-effects whilst throwing away its output."

    However, I disagree with this reason.

    The issue with "throwing away its output" was resolved, about 14 years ago[perlhist], in Perl 5.8.1. From "perl581delta: Miscellaneous Enhancements":

    "map in void context is no longer expensive. map is now context aware, and will not construct a list if called in void context."

    The reason I would give for not using map in void context is based on efficiency. I've had reason to benchmark map vs. for on a number of occasions over the years: I've always found for to be measurably faster than map; and, unsurprisingly, map EXPR is faster than map BLOCK.

    Here's a very quick and dirty benchmark I just wrote to show this:

    #!/usr/bin/env perl use strict; use warnings; use Benchmark 'cmpthese'; my @x = 0 .. 99; cmpthese 1e6 => { map_expr => sub { my @y = @x; map ++$_, @y; return }, map_block => sub { my @y = @x; map { ++$_ } @y; return }, for => sub { my @y = @x; ++$_ for @y; return }, };

    I ran this five times. All results were much the same. This one was roughly in the middle:

    Rate map_block map_expr for map_block 75019/s -- -44% -47% map_expr 134953/s 80% -- -5% for 141844/s 89% 5% --

    Benchmark run using:

    $ perl -v | head -2 | tail -1 This is perl 5, version 26, subversion 0 (v5.26.0) built for darwin-th +read-multi-2level

    — Ken

      "map in void context is no longer expensive. map is now context aware, and will not construct a list if called in void context."

      Hi Ken, I wasn't referring to "throwing away the output" in terms of wasted resources, but rather in terms of unclear code.

      map is a function that returns a list -- when it is used in void context it smells bad, because it forces the reader to double-check that the author didn't make a mistake, falling into the same general category as any other distracting syntax or idiom.

      It's also a bad habit in general to use functions for their side effects, as those may change.


      The way forward always starts with a minimal test.

        All good. As I said, I "agree" with not using it in that fashion. Sorry if I misinterpreted your reason, with which I said I "disagree".

        I would rarely use map in void context, nor have I often seen others code it that way, so "unclear code" has never really been much of an issue; however, I don't disagree that it could lead to confusing or distracting syntax.

        — Ken

      Timings could change from one version of perl to the next, so this kind of micro-optimization is meh. I would tend to use for over map myself in this situation, but it doesn't seem to matter all that much at this point. Whatever you do, don't write this:

      @smb = map { s/\s+\z//; $_ } @smb;

      Yes, I've seen people who habitually write this kind of thing. I don't know where they learned it.

Re^3: Open Filehandle once
by thanos1983 (Parson) on Aug 24, 2017 at 23:22 UTC

    Hello 1nickt,

    You are right I completely forgot about it. Thanks for the observation of map also. See my updated answer, BR.

    Seeking for Perl wisdom...on the process of learning...not there...yet!