Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Use globals or pass around everything under the sun?

by greywolf (Priest)
on Dec 04, 2001 at 10:15 UTC ( [id://129273]=perlmeditation: print w/replies, xml ) Need Help??

At work we are completing a rather large CGI application. The main program is only a couple hundred lines long (it mostly directs traffic) and all of the work is done with about a dozen modules. We use the term module loosely as each of these modules is pretty much a program of it's own.

Session variables are read from the database in the main program and again in each module. I don't have any previous experience handling sessions so I don't know if this is the norm. I have written some of the more recent modules so they don't use any session variables themselves. In these I am passing in every variable I will need when I call the module. This list has gotten as large as 30 variables for some modules, and it would be a lot larger for other modules.

I feel that passing in a large number of variables makes the code cleaner. The other programmer feels that re-creating the variables will slow down the application. Obviously we have differing views as to the merit of each approach. Since we are just about finished this version and getting ready to start the next version we want to come an agreement as to the best solution.

I know I am being rather vague but my questions are these:
1) Is it better to use sessions in modules like this?
2) Is it better to pass in every variable under the sun?
3) Will one approach make the application faster/slower than the other?
4) Do you feel that either/both of these approaches is just plain bad?

Any tips and pointers will be appreciated.

mr greywolf
  • Comment on Use globals or pass around everything under the sun?

Replies are listed 'Best First'.
Re: Use globals or pass around everything under the sun?
by maverick (Curate) on Dec 04, 2001 at 11:54 UTC
    My advice is always to avoid global vars whenever possible. They are most always bad (say "I have 30 global variables, is that too many?" in the chatterbox and what happens). Machines are fast. Ram is cheap. I'd rather add a few clock cycles to the execution time than add a few hours to the debugging time.

    As for a technique to apply... Instead of having 30 separate variables floating around, stuff similar groups of variables into either a module (as previously described) or use a hash. I describe the technique for using a hash here. Basically this is a best of both worlds scenario...to pass ALL your vars to your module you only have to copy 1 scalar if you us a hash ref (your coworker's big problem), you don't have tons of globals, and you don't have to remember the exact sequence of the 30+ vars you passed in.

    HTH

    /\/\averick
    perl -l -e "eval pack('h*','072796e6470272f2c5f2c5166756279636b672');"

Re: Use globals or pass around everything under the sun?
by BMaximus (Chaplain) on Dec 04, 2001 at 11:55 UTC
    Ok, repeat after me ...
    "Global variables are bad"
    "Global variables are bad"
    "Global variables are bad"
    "Read Code Complete by Steve McConnell"

    As you can see I try to avoid global variables at all cost. If the number of variables your are passing to modules/functions is over 10. You need to take a look at what you're doing again and rethink it. Try to combine variables that are related and pass them as a hash.

    Look at CGI::Application as a large framework for web applications. If its a stand alone program you can still get an idea as to how you can organize things.

    You're not too clear as to what you're doing. But in any application if you're passing too many variables in to give it information, you're more likely to have problems. Both in tracking down where it is and how many crop up as well as how much time it takes to create it. Try to break the task down as much as you can. You'll find you can reuse code in a lot of places and save a lot of time.

    The more you reduce the load on the database, the better your application will run. Though having 30 or more variables going to a module won't slow the application down, it just makes it more complicated. Just remember you have to keep track of all those variables.

    Work on getting the job done first, then optimise it for speed.

    BMaximus
Re: Use globals or pass around everything under the sun?
by jepri (Parson) on Dec 04, 2001 at 11:08 UTC
    1: Since you have to use session variables your questin reduces to "where should I use sessions variables", I think. I'm a bit of a fan of the load once access from everywhere method.
    2: Rather than pass, you are allowed to have a module called Session::Parameters, or something silly like that. Call the session loader when the script starts and then all modules can access that module's namespace. Whenever you think global variables might be useful, pop them in a module instead. Then all modules access Parameters::UserInfo or whatever you called it.
    3: Yes.
    4: Not bad, but cumbersome. Global variables are not always wrong, just almost always wrong. All comments about side effects from routines apply here.

    ____________________
    Jeremy
    I didn't believe in evil until I dated it.

Re (tilly) 1: Use globals or pass around everything under the sun?
by tilly (Archbishop) on Dec 04, 2001 at 18:33 UTC
    My reaction to what you describe is that both of you need to improve on design so that you don't think that you really need 30 variables all of the time. I wish I had a simple way to tell you how to do that, but without understanding why you are getting into that bind, I cannot really tell you how to avoid needing that many variables. (I suspect that understanding that phrase, Think loose coupling that you see from time to time on pages here might help.)

    But after that, both solutions have problems. Globals raise the possibility of promiscuous interaction between code, which causes all of the usual debugging issues. Passing variables protects you from that, and documents what you are using, but raises issues with how your argument lists are structured. If you are positionally placing 30 arguments, then you are using copy and paste. What happens if you want to add an argument? Hopefully you are using hashes to allow you to work by name.

    Likewise the answers that people are offering have issues. If you start using hashes, how do you do typo checks? I have offered solutions to that in the past. But most of those solutions (rightly IMO) require you to wind up carefully thinking through which variables are needed in which functions. Passing references to hashes you directly access is likewise problematical for the reasons that I stated at Pass by reference vs globals.

    No. The real problem is that you are trying to manage a large amount of common data. That is a task which raises inherent issues. And solving that is probably a design issue.

Re: Use globals or pass around everything under the sun?
by dragonchild (Archbishop) on Dec 04, 2001 at 18:32 UTC
    Use hashes or, even better, hashes-that-can-have-methods-called-through-them (aka, objects). This will allow you to bundle stuff.

    (You will be using references to hashes, not the hashes themselves, right?)

    You are correct in that passing in tons of variables will make the code cleaner. You have an interface between the main program and the modules.

    As for the other programmer's thoughts, he's probably right. But, he also suffers from premature optimization. Is passing the variables around causing a noticeable slowdown? If it isn't, then there's nothing to optimize!

    My suggestion would be to try them both.

    What's that you say? Too much work? Your implementation is too tightly tied to your interface? Sounds like you've got work ahead of you. :-)

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      Im so glad you posted this. Its basically what I was going to say too.

      Whenever I find I am dealing with large numbers of parameters getting passed around I create an object to hold them all, and then either pass it around or subclass it.

      One advantage to having an object to pass around is that it provides an single point that the programmer can go to see what possible variables exist. This is in some respects better than subclassing as you dont have zillions of layers of additional stuff.

      My only criticism of you post is that IMO there should not be more than a few parameters to a suboutine. The more parameters a subroutine takes the more difficult it is to understand what it does, and to make mistakes with regard to their position (addmittadly this can be dealt with via named parameters) or omission. Usually this isnt that big a deal, except that it can have a dramatic slowdown on development time and frustration levels.

      Yves / DeMerphq
      --
      Have you registered your Name Space?

        Heh. I wasn't going to get into refactoring, though that sounds like what's needed here...

        ------
        We are the carpenters and bricklayers of the Information Age.

        Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Re: Use globals or pass around everything under the sun?
by lachoy (Parson) on Dec 04, 2001 at 12:59 UTC
      While I didn't comment in that thread, my sympathies went with jbert at Re: how to make a universally inherited method?. In particular I fail to see what using singletons in this case really buys you over using strict.pm and exporting variables from a configuration module using Exporter. (Other than buzzword compliance that is.)

      There are valid uses of a Singleton pattern where it is a win. If producing your variable is expensive, and so you want to do it lazily, then Singletons are great. They are then basically an OO way of expressing memoization. But for just expressing configurations, what is the big win supposed to be?

        It's probably just me, but I find exporting variables for configuration purposes just as bad as a global variable. I hate polluting namespaces except for CONSTANTS, even when the coder asks for it, and always fully qualify all non-method subroutine calls. Paranoid? Maybe, but I think it's made my code easier to understand down the road.

        As you said, it's basically the same thing as exporting a variable but with an extremely lightweight wrapper around it that explicitly tells you (the maintainer twelve months down the road after the original programmer has left) there's only one configuration object out there. TMTOWTDI.

        Chris
        M-x auto-bs-mode

        When I supported the use of singletons in that thread, it was to say that anything is better than a bunch of globals. What I was proposing was exporting wrapper functions using Exporter. I also don't know the definition of a singleton, so I was guessing from context. I think I guessed wrong. :-)

        ------
        We are the carpenters and bricklayers of the Information Age.

        Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Re: Use globals or pass around everything under the sun?
by greywolf (Priest) on Dec 05, 2001 at 21:37 UTC
    Thanx for the replies and the info everyone.

    You have given me some good ideas to think about. While I am not the head designer of this project I will be sure use as much as I can.

    mr greywolf

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (2)
As of 2024-04-26 01:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found