This entire thread never even mentioned @_ once! It mentioned $_[0] exactly once but never used it in code.

So I'll be the first to mention:

my %h= %{ shift @_ };

Leaving the target of operations implied is fine for quick hacks, one-liners, and golf. But I usually stress writing code that is easy to maintain so I usually avoid such implied targets. And this means I don't get bit by shift or pop being treated as a string.

It also means that you can easily find where I deal with function arguments. As opposed to this code from a core module. Quick, what arguments does it take?

sub ... { my ($pkg,$file,$line) = caller($TestLevel); my $repetition = ++$history{"$file:$line"}; my $context = ("$file at line $line". ($repetition > 1 ? " fail \#$repetition" : '')); my $ok=0; my $result = to_value(shift); my ($expected,$diag); if (@_ == 0) { $ok = $result; } else { $expected = to_value(shift); my ($regex,$ignore); if (!defined $expected) { $ok = !defined $result; } elsif (!defined $result) { $ok = 0; } elsif ((ref($expected)||'') eq 'Regexp') { $ok = $result =~ /$expected/; } elsif (($regex) = ($expected =~ m,^ / (.+) / $,sx) or ($ignore, $regex) = ($expected =~ m,^ m([^\w\s]) (.+) \1 $ +,sx)) { $ok = $result =~ /$regex/; } else { $ok = $result eq $expected; } } my $todo = $todo{$ntest}; if ($todo and $ok) { $context .= ' TODO?!' if $todo; print $TESTOUT "ok $ntest # ($context)\n"; } else { print $TESTOUT "not " if !$ok; print $TESTOUT "ok $ntest\n"; if (!$ok) { my $detail = { 'repetition' => $repetition, 'package' => $ +pkg, 'result' => $result, 'todo' => $todo }; $$detail{expected} = $expected if defined $expected; $diag = $$detail{diagnostic} = to_value(shift) if @_; $context .= ' *TODO*' if $todo; if (!defined $expected) { if (!$diag) { print $TESTOUT "# Failed test $ntest in $context\n +"; } else { print $TESTOUT "# Failed test $ntest in $context: +$diag\n"; } } else { my $prefix = "Test $ntest"; print $TESTOUT "# $prefix got: ". (defined $result? "'$result'":'')." ($context)\n"; $prefix = ' ' x (length($prefix) - 5); if ((ref($expected)||'') eq 'Regexp') { $expected = 'qr/'.$expected.'/' } else { $expected = "'$expected'"; } if (!$diag) { print $TESTOUT "# $prefix Expected: $expected\n"; } else { print $TESTOUT "# $prefix Expected: $expected ($di +ag)\n"; } } push @FAILDETAIL, $detail; } } ++ $ntest; $ok; }

At least the suggested %{shift()} makes the code somewhat clearer. But both %{+shift} and %{(shift)} are, if anything, somewhat obfuscatory, which isn't an awful thing, but since there are such clearer alternatives I don't consider them good options.

- tye        


In reply to Re: Pass By Reference Inner Workings - Magic scalar operator (@_ FCS) by tye
in thread Pass By Reference Inner Workings - Magic scalar operator by geekondemand

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.