in reply to Re: Pivoting 2 dimensional array refs
in thread Transposing 2 dimensional arrays

Nice. It's fundimentally the same, but you get a lot of collapse of excess code by folding up the if/else decision when computing $value.

I would normally, in any language, spot that construct:

if (something) value = xxxxx else value = yyyy
as something to be folded up into one expression. Perhaps a terinary operator: value = (something) ? xxxxx : yyyy. But the "defined or" really shines here, reeling in the rest. That is precisely the idiom that the OP needs in the problem: grab the value at the source coordinates, but make it '' instead of undef.

I see that the computation of max_col was made into one line by using the suffix form of 'for'. That shrunk the vertical expanse of code down quite a bit.

Replies are listed 'Best First'.
Re^3: Pivoting 2 dimensional array refs
by Voronich (Hermit) on May 14, 2011 at 14:11 UTC

    I once thought as you do ;).

    Unless there is a performance gain that is:

    1. Truly significant
    2. Actually needed
    I stay away from ternary assignment and other forms of code collapse in favor of more verbose easy to read code. I'd far rather opt for clear suboptimal code than optimized idioms that don't really give me much.

    Now if there's actual redundancy I'm more inclined to squnch it up.

    But I suspect this largely talks past your point of the 'defined or' which, as I'm packing, I haven't yet had time to cogitate over.

    o/

    Me
      More verbose doesn't mean easier to read. The separate branches means I have to read through and grasp that the LHS is the same, and then re-arrange it in my mind to the higher-level idea: set LHS to one of two things depending on condition.

      Writing the more concise form more closely represents the higher-level meaning. That doesn't mean you have to make it overly terse: write it on separate lines:

      $value= (condition) ? this : that ;
      It's no different than using a for loop instead of a while, to put the different parts of the idiom together.

      For sequential steps, I'll certainly write it on multiple lines with named variables for the intermediate values, rather than cramming it into one huge nested statement. But this is not like that. Spreading it out makes it harder to read.

      More specialized forms, like the one he used (//), are idiomatic in Perl. open or die. $normal // $blank.

      You say "optimized idioms". Well, I think we are speaking across purposes. Nesting a bunch of stuff instead of writing separate statements doesn't make it any clearer. But using a well-known idiom gives a higher-level impression of its meaning, what it's used for and the specific nature of the problem it is addressing.

      If you don't know them yet, sure they are confusing because the writer doesn't need to comment in detail what those issues and solved problems are — the use of the idiom says it all. But once you learn why a particular twist of the keyboard is written that way, maybe read a whole essay about it, then you just follow that example and consider the matter settled.

      As for cocnating the "defined or", you might want to start with the regular logical || and its low-precedence counterpart or. Look how it's different from C, in that the result of the expression isn't just "true" but the value from the first true argument. They are used tersely like footnotes: if that normal way didn't work out, use this instead. Or as control-flow, picking the first one that applies.

      If I have a parameter $x, and the caller can leave off the parameter and mean the default value of 42, you can write, in the body of the function $x//42. Or you can set it if it's not passed, with $x //= 42;. The pulling of the data from the matrix with missing values is the same: give me xy, but if that's not available, use blank instead.

      The code you learned for opening files uses this kind of control flow too:

      open FILE, '<', $fname or die "Can't open $fname";

        I think you're right. Certainly additional whitespace isn't inherently virtuous ;).

        I spent some idle cycles trying to figure out what I don't like about the $a = (b) ? c : d; notation, while being fine with the same construct in the 'open' case and as strange as it may sound I think it's that the former doesn't read in natural language very well, being "assign lvalue if condition from value otherwise from alternate." But open is "open file or die" which flows much easier when reading down the code.

        Me

      Are you really saying that you find

      if( cond ) { $var = val1; } else { $var = val2; }

      Substantially clearer or easier to code or understand than

      $var = cond ? val1 : val2;
      ?

      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        Actually, just enough to not do it, yeah. I always have to double-take ternary assignments.
        Me
        No no, that is still to confusing, you need more newlines
        if( cond ) { $var = val1; } else { $var = val2; }