Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Where to put my variables...

by ravendarke (Beadle)
on May 31, 2002 at 20:31 UTC ( [id://170827]=perlmeditation: print w/replies, xml ) Need Help??

I'm sitting at my desk, hacking away at some code, when I had a question about the use of my. Not how it works, or anything like that. Nor do I want to do away with it. I use strict (I have been listening, O! Monks). No, the question I had was, for style and readability, where do you declare your variables? My first language was Ada, where I really had no choice. dvergin said "A common rule of thumb is that you want to declare the variable in as narrow a scope as you can and still be able to access it where you need to." in this discussion, but aside from the function, what do you find to be easier to read and/or maintain? Predeclaring variables, or declaring them as you need them?

Marty

Update: Fixed the code tag I goofed... Sorry about that..

Replies are listed 'Best First'.
Re: Where to put my variables...
by tadman (Prior) on Jun 01, 2002 at 00:00 UTC
    Some languages don't allow you to put your variables where you need them, they force you to declare things up front. C is like this, but this was fixed in C++. Perl allows you to declare variables virtually anywhere, which keeps things neat and tidy.

    My advice is to keep your variable definitions as close as possible to where they are used, or to group them together logically in a sensible location. These can sometimes be contradictory, though, so it's often a matter of judgement. There are advantages to both strategies.

    Each sub-routine is like a mini program. It has "globals", it has local variables, and it has sub-blocks that have their own variables. In a recursive sense, the same rules you use to organize your main program apply to each sub-block, all the way down.

    Here's an example of what I would categorize as poor technique:
    sub foo { my ($foobar, $frurab) = @_; my @foo = split(/,/, $foobar); my $bar; my $x; foreach $x (@$frurab) { $bar .= $x->foo(); } foreach $x (@foo) { $bar = "<$x>$bar</$x>"; } return $bar; }
    Something that can set people's hair on fire is these Omni-Variables, these things called $x or $i or $foo which take on completely different roles at different points. In this example, $x is an object, and then later, a scalar. Talk about a personality disorder. When debugging, there is no certainty about what $x is going to be. If, instead, each foreach loop had its own properly named variable, things would be quite clear.

    Also, the @foo variable is not very useful, and seems to just take up space for most of the routine even though it is used only briefly. You could just inline the split and save yourself the variable and the associated memory overhead.

    Here's take 2:
    sub foo { my ($foobar, $frurabs) = @_; my $return; foreach my $frurab_entry (@$frurabs) { $return .= $frurab_entry->foo(); } foreach my $tag (split(/,/, $foobar)) { $return = "<$tag>$return</$tag>"; } return $return; }
    Now you have two different variables, each named specifically according to what they are. Now, instead of wondering what your seecond loop was iterating over, and having to check back in the function to find out, it is presented right there for you to see.

    It's kind of like a "Just In Time" delivery system, only for variables. You don't keep stuff laying around. You create it when you need it, and you get rid of it as soon as possible. Remember that as soon as your foreach loop ends, all the local variables are liberated, and with them, any memory used. In big, deep functions, this can really cut back on resource consumption.

    In the second example, the split version of $foobar is created and used and destroyed in a relatively brief period of time. In the former, it persists for the entire duration of the function, which could be some time. You can imagine how lots of little things like this can add up to a really big thing.
Re: Where to put my variables...
by talexb (Chancellor) on May 31, 2002 at 20:57 UTC
    I think dvergin has pretty well covered it -- declare the variables right when you're going to use them.

    The exception for that would be when you have quite a large subroutine (one module that I wrote and still maintain is 2000 lines long, and mostly consists of a single routine 1750 lines long) -- in that case I put virtually all of my variable declarations at the top of the routine. That way there was less searching for variable declarations scattered around.

    --t. alex

    "Nyahhh (munch, munch) What's up, Doc?" --Bugs Bunny

Re: Where to put my variables...
by Steve_p (Priest) on May 31, 2002 at 22:05 UTC
    I was brought up in programming on a strict diet of Pascal, PL/SQL, and COBOL, so I know all about predeclaring my variables. This was still my standard in the C, Perl, and Java code as well. After reading Refactoring, I decided that it was time to make the switch. The problem with having your variables someplace other than where your using them is that it make code maintanence nasty. Say you have a somewhat long function of about 60-80 lines of code (this shouldn't happen after refactoring, but I digress). If all your variables are declared at the top of your procedure, you generally have to scroll up and down to figure out what their doing. If the scope of your variables is narrow, then you should see everyplace its used on one screen. That makes the lives of the programmers that come after you much easier.
      However,the problem of not being able to figure out what a variable is doing is handled by using sensible, descriptive variable names.
        That works much better if cow-orkers never misuse your carefully named variables.

        In the real world, being able to verify that this variable has a scope of 5 lines and isn't misused there does wonders for debugging.

Log In?
Username:
Password:

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

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

    No recent polls found