http://www.perlmonks.org?node_id=1073281


in reply to Re: Make $^V and "my" implicit
in thread Make $^V and "my" implicit

defined-or (or //) is not about speed: it is about logic and concise programming: it improves legibility and maintainability. I use the feature since perl-5.8.0 and it has been a very good reason to upgrade all my perl installations, even with customer sites. I cannot think of writing any perl script that does not use this feature. Silently I still wish the low-precedence keyword err (or dor given a bikeshed argument) will return one happy day.

Now imagine writing this with ternary:

my $file = $options{file} // $options{input_file} // get_default_option (""file") // get_default_option ("input_file") + // file_exists ("$ENV{WORK_DIR}/file.in") // file_exists ("$ENV{HOME}/project_in.file") or die;

Or, preventing warnings

printf "%-20s: %s\n", $_, $options{$_} // "<undef>" for keys %options; function (map { $_ // "default" } @values); my @sorted = sort { ($a->{order} // 0) <=> ($b->{order} // 0) } @aoh;

Enjoy, Have FUN! H.Merijn

Replies are listed 'Best First'.
Re^3: Make $^V and "my" implicit
by boftx (Deacon) on Feb 04, 2014 at 01:13 UTC

    Okay, the first example hurts just to look at it. :) But I will agree that overall using //= is more concise, cleaner. My point is that it should not be an overriding factor when writing code that is intended to be used out in the wild in unknown environments.

    The second example (preventing warnings) can just as easily use || and get the same results as //. That said, I have used your example many, many times when writing for a closed environment, mostly for the reasons you give.

    It helps to remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.

      The second example (preventing warnings) can just as easily use || and get the same results as //. That said, I have used your example many, many times when writing for a closed environment, mostly for the reasons you give.

      No, it cannot, as 0 in most cases is a valid value, very valid. With || it would be replaced.

      Just use it, and see how many unmeant problems suddenly disappear.

      Where || does work well, is when the default for a value is 0, most of which are boolean-like values:

      my $hidden = $cell->{Hidden} || 0;

      true values stay, false values (undef, "", 0 and "0" all get replaced with 0. Replacing 0 with 0 does not hurt.


      Enjoy, Have FUN! H.Merijn

        I was looking specifically at this line:

        my @sorted = sort { ($a->{order} // 0) <=> ($b->{order} // 0) } @aoh;

        In that case, || would indeed give the same result. The same goes if one were dealing with char data and used $foo || ''. Granted, in those cases the assignment would be redundant, but the warning would be avoided when the value in question is not defined. (Which ignores the question of whether or not it should be avoided since it might be an indication of working with bad data to begin with.)

        That said, you and I can both point to cases where what you are saying would be true, especially in the case of char data and having '' (empty string) replaced by a non-empty default would be an error. But in my experience that is the exception to the general use-case and is not a serious problem to deal with.

        It helps to remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.
Re^3: Make $^V and "my" implicit
by Anonymous Monk on Feb 04, 2014 at 00:31 UTC

    Now imagine writing this with ternary:

    Why torture yourself?