Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Perl Style: Is initializing variables considered taboo?

by ait (Hermit)
on Aug 21, 2010 at 13:50 UTC ( [id://856453]=perlquestion: print w/replies, xml ) Need Help??

ait has asked for the wisdom of the Perl Monks concerning the following question:

Hi,
Since I started using Perl I've always initialized my variables, many times with undef, but I've seen a lot of CPAN code that doesn't.
Maybe it's considered wasteful or uncool?
  • Comment on Perl Style: Is initializing variables considered taboo?

Replies are listed 'Best First'.
Re: Perl Style: Is initializing variables considered taboo?
by BrowserUk (Patriarch) on Aug 21, 2010 at 14:01 UTC

    If you're using my, initialising with undef is just make-work, as lexical variables are automatically initialised to undef.

    If you're not using my, then this is another reason to start.

      I don't understand ... Why you are restricting this behavior to my...?

      Every non-initialized variable is not defined.

      DB<1> print $a // "undef" undef DB<2> my $a;print $a // "undef" undef DB<3> our $a;print $a // "undef" undef DB<4> $a=1;print $a // "undef" 1
      UPDATE:

      And in most cases accessing an undefined variable will be caught under use warning;.

      DB<1> print $a DB<2> use warnings; print $a Use of uninitialized value $a in print at (eval 6)[/usr/share/perl/5.1 +0/perl5db.pl:638] line 2. .. DB<3> use warnings; $a=undef;print $a Use of uninitialized value $a in print at (eval 9)[/usr/share/perl/5.1 +0/perl5db.pl:638] line 2. .. DB<4> print $a++ 0

      Notable exceptions of this warnings are some altering operators like ".=" and "++" and auto-vivication in hashes and arrays.¹

      Cheers Rolf

      1) anything else?

      ... of course boolean context including the defined operator won't throw a warning.

        Why you are restricting this behavior to my...? Every non-initialized variable is not defined.

        Unless is was used in module you called, or the previous iteration of the loop, or call to sub, or ...

        They may start out as undef, but only for the first use.


        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.
      Of course I use strictures in all my code! Why else would I be asking about variable initialization if I did not predeclare them?
      The question was more on style (hence "Perl Style") and the fact that the pod for my in perlfunc does not specify if it actually initializes the variable to any specific value.
      Nevertheless, after your response I discovered that perlsyn pod does under "Declarations" and quite extensively explains the initialization details. It seems that in a few cases it is wise to initialize, but not to undef, because as you say, it is just plain wasteful. Though IMHO I still think it just looks neater in the code, but shall refrain from doing so to undef in the future.
      I have a faint memory that I picked up the practice many years ago from the Camel book (or PBP), and I think it states somewhere that it is good practice to always initialize variables, but I could be wrong... or maybe it's just an old habit from my background in C.
        there are cases where assigning undef makes sense but generally it's a waste of time (which is not Perl style ;)

        Applications are especially when passing "positional" lists or assigning to lists, with "gaps".

        i.e.

        ($a,undef,$b)=@array; # ignore second parameter
        or
        function($a,undef,$b) {..} # treat second parameter as not suppl +ied

        The latter is especially necessary if you are checking arguments within the sub for definedness and changing to default values.

        UPDATE: An extension of this case is a hash or array element which exists but is not defined!

        > Of course I use strictures in all my code!

        it's more about use warnings to be warned about undefined variables.

        UPDATE:

        and please be careful not to return undef to "explicitly" return false.

        Subs return lists, so what you are actually doing is returning a one-element list instead of an empty one. I.e. @array=func();

        Using a blank return is the same like return (); and won't byte you in list context but in scalar context the variable will be undef anyway.

        Cheers Rolf

        Of course I use strictures in all my code!

        I did say "if". Not everybody uses strict; and I don't know you from the next guy; so there is no "of course" about it.

        Why else would I be asking about variable initialization if I did not predeclare them?
        Because initialising/reinitialising your variable to undef becomes very important if you don't use my, because globals have this habit of retaining their values from previous iterations of loops, and previous calls to subroutines.

        As for style, that is in the eye of the beholder. I find much perlstyle a total anathema; often supported by nothing more than justifictions.


        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.
        I've read through the posts and there is certainly a lot of verbage here!

        As long as you aren't using the very ancient C style where all the variables had to be declared at the beginning of the sub instead of when they are first used or close to where they are first used as in modern C, I don't see any problem at all.

        Often I see my @x=(); vs just my @x;, but I don't see any big point to get really riled up about! I seldom see a statement with a scalar like my $x=undef; vs my $x; because something happens with $x in the next line or two. An array or hash declaration happens more often closer to the beginning of the code and can have a wider distance between declaration and use.

        Of the universe of style issues, this issue probably shouldn't be at the "top of your hit parade".

Re: Perl Style: Is initializing variables considered taboo?
by ikegami (Patriarch) on Aug 21, 2010 at 15:45 UTC

    Some people like to differentiate "doesn't have a value yet"

    my $x;

    from "has the value undef (or false)

    my $x = undef; my $x = 0;

    Perl, of course, doesn't case. It's stylistic semantics.

    Now, if you do the following, it's a bit silly:

    my $x = undef; if (cond()) { $x = f(); } else { $x = g(); }
Re: Perl Style: Is initializing variables considered taboo?
by cdarke (Prior) on Aug 21, 2010 at 17:05 UTC
    The standard references for style are perlstyle and Perl Best Practices, and neither say anything about initialising variables specifically. PBP says to initialise localised variables, but you specifically mention my. PBP also says to initialise attributes, but again that's probably not what you mean.

    perltidy does not appear to care, and Perl::Critic is silent on the matter.

    My view is that if you have a good reason to initialise them then do so, if not, why bother? You don't have to impress anyone else, do you?
      As to impress no, though I usually try to make code look good as well as it works.
      Initializing variables to something has seemed neater and more legible, though I had never given it much thought till today. For example this IMO looks neater:
      my $foo = 0; my $bar = undef;
      Than this:
      my $foo = 0; my $bar;
      I think ikegami understood perfectly where I was comming from with this thread.
        IMHO there is no possibility in Perl to distinct between:

        my $a and my $a=undef

        "Assigning the value undef" (dangerous discription) of a scalar is always completely transparent to "has no value at all".

        If I'm wrong, I'd appreciate if someone can show me code proving me false.

        Furthermore you can't safely use "value comparisons" with undef.

        DB<33> my $a; print $a==undef 1 DB<34> my $a; print $a==0 1 DB<35> my $a=undef; print $a==0 1 DB<36> my $a=undef; print $a eq undef 1 DB<37> my $a=undef; print $a eq 0 DB<38> my $a=undef; print $a eq "" 1

        you need to use the special builtin defined.

        Thats why I think it's the better stile to avoid undef if not necessary.

        When you need to reset already declared and potentially initialized variables (in the sense of "setting to an non intialized state"):

      • for multiple vars you can assign an empty list:
        ($a,$b)=();

      • to reset a single scalar you can alternatively chose to write:
        undef $a;
        (but actually I never do this myself)

        Cheers Rolf

Re: Perl Style: Is initializing variables considered taboo?
by shawnhcorey (Friar) on Aug 21, 2010 at 15:54 UTC

    One of the problems of mod_perl was that it didn't initialize variables; it simply reused the space. This meant that your uninitialized variables would have data from the previous incantation. I do believe that this has been fixed but there's no harm in initializing them anyway.

    I always initialize them in case something like this happens again in the future. Just because you're not paranoid doesn't mean computers don't hate me. :)

      my $x; initialises. Any trailing = is just a normal assignment that occurs after the variable has already been created and initialised.

      The only situation I can think of is if you do

      my $x; sub foo { ...[ use $x ]... }

      If you use that as a Registry script, you'll have problems. Perl tells you about it with "will not stay shared" warnings. The fix is NOT to ignore the warning. You could fix it by switching to a package variables.

      our $x = undef; sub foo { ...[ use $x ]... }

      Unlike my, our doesn't initialise, so you have to initialise yourself.

      * — The implementation varies a little, but you shouldn't notice any difference unless you do something disallowed like my $x if $cond;

Re: Perl Style: Is initializing variables considered taboo?
by rowdog (Curate) on Aug 21, 2010 at 17:05 UTC

    I cut my teeth on C so I suppose that's why I never assume any variable has a value until I give it one.

    my $var = undef; means that I plan to use $var and I care that the value is undef.
    my $var; means I plan to set the value later. Usually, I'm just declaring $var in an outer scope and this shows that.
Re: Perl Style: Is initializing variables considered taboo?
by dmz (Novice) on Aug 22, 2010 at 03:36 UTC
    Dont forget my @this = undef; or my %that = undef; dump either and you will see that empty array element or hash element. $this[0] = update; or $that{} = undef; That's screwed up my sql inserts so may times! i now never declare unless a variable being undef is actually integral to the function of the program. $return for example Namasté Monks!

      You should set arrays and hashes to the empty list.

      my @this = ();
      my %that = ();

        Why?

        Have you ever had a declared array or hash not contain an empty list?

Re: Perl Style: Is initializing variables considered taboo?
by JavaFan (Canon) on Aug 22, 2010 at 22:16 UTC
    Since I started using Perl I've always initialized my variables, many times with undef, but I've seen a lot of CPAN code that doesn't. Maybe it's considered wasteful or uncool?
    I usually "declare" my variables on first use - or phrased differently, as soon as I "declare" my variables, I use them. Which, for scalar variables, usually means they immediately get a value (unless I just want their reference). But if they get a value, it usually isn't "undef". I find both
    my $x;
    and
    my $y = undef;
    to be pretty wasteful. I prefer
    my $z = shift; my $w = $hash{foo}; my ($v, $u) = /pattern/g; while (my ($s, $t) = each %hash) {...} while (my $r = <>) {...} ...
Re: Perl Style: Is initializing variables considered taboo?
by FloydATC (Deacon) on Aug 24, 2010 at 15:58 UTC
    If the undef has a significant meaning, I define it explicitly to make the code as clear as possible. Otherwise, I spend my keystrokes elsewhere. For example:
    my $found = undef; foreach my $candidate (@candidates) { if ( good($candidate) ) { $found = $candidate; last; } } if (defined $found) { print "Found a good candidate: $found\n"; }

    -- Time flies when you don't know what you're doing
Re: Perl Style: Is initializing variables considered taboo?
by sundialsvc4 (Abbot) on Aug 24, 2010 at 23:34 UTC

    I would summarize my feelings on the matter thusly:

    1. No matter what else you do, be crystal-clear.   Also avail yourself of everything that Perl can do for you through the use of:
      use strict; use warnings;
    2. Remember that the mod_perl (and FastCGI) environment is persistent.   The program may remain in memory for some time, and this can create severe debugging issues unless you make it a point to ensure that every single thing has a known value (or is known to have no value) at all times.
    3. Perl has many debugging tools, analyzers, and regression-testing tools.   You see them used in major CPAN modules all the time.   There are many benefits indeed to be gained from the practice of building your own modules to an equal degree of rigor.   Many of the CPAN modules we use today evolved from this practice.

    One of the nice things about the Perl world is that “best practices” about a great many things are both carefully spelled-out, and carefully explained.   In the true spirit of TMTOWTDI, you don’t have to follow them.   But it is invariably wise to do so.

Re: Perl Style: Is initializing variables considered taboo?
by james2vegas (Chaplain) on Aug 25, 2010 at 17:16 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://856453]
Front-paged by tye
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (8)
As of 2024-04-19 07:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found