Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
my $self = shift if (ref $_[0]); my($arg1,$arg2,$arg3)=@_;

Eeek! This sort of thing can rapidly get you into serious trouble. First of all, there's the fact that this won't operate properly if it's called as a class method such as Some::Package->foo( qw(arg1 arg2 arg3) ); $_[0] is a string, in that case.

Secondly, it breaks down if you pass in a normal reference as your first argument. foo({'hashkey' => 'hashval'}, qw(arg4 arg5)); You end up setting a normal arrayref as $self.

And thirdly, and potentially most importantly, if the conditional fails, then the variable maintains its scope. There are other threads on the board talking about the pitfalls of constructs like my $xyz if 0, which is what can happen here. The short answer is in this case $xyz would end up acting like a static variable. The first time, it gets initialized to something random (well, not random - it's 0 (or undef?), but that's not guaranteed and could change at any time (not that it has) ), and on subsequent calls, it maintains its value.

It doesn't directly cause problems here, probably, but observe this contrived function.

sub foo { my $self = shift if (ref $_[0]); $self++ unless ref $self; my($arg1,$arg2,$arg3)=@_; print "($self)($arg1)($arg2)($arg3)\n"; } foo(qw(a1 a2 a3)); foo(qw(a3 a4 a5)); Output: (1)(a1)(a2)(a3) (2)(a3)(a4)(a5)

Note how $self survived between calls and was around to increment. Bugs of this nature can be horrible to track down. It's also frowned upon to try to use this for static variables - use a closure or wrap the subroutine in an additional lexical scope to have "static" variables scoped to the subroutine. Besides, it's tougher to read this way. In general, it's best to always avoid my $foo if $something constructs, except for obfuscated contests or the like.

In reply to Re^2: shift vs @_ by jimt
in thread shift vs @_ by Zadeh

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, 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, 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.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others scrutinizing the Monastery: (5)
    As of 2018-02-22 15:04 GMT
    Find Nodes?
      Voting Booth?
      When it is dark outside I am happiest to see ...

      Results (294 votes). Check out past polls.