Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re^2: Global variable vs passing variable from sub to sub

by BUU (Prior)
on Sep 14, 2004 at 10:10 UTC ( #390780=note: print w/ replies, xml ) Need Help??


in reply to Re: Global variable vs passing variable from sub to sub
in thread Global variable vs passing variable from sub to sub

I don't understand the last line of:
sub account_over_limit { my ($account, $balance) = @_; return exists $LIMITED_ACCOUNTS{$a­ccount} && $balance > $LIMIT; }
This is incredibly simple perl code. It simple accesses a hash and compares a scalar to another scalar. If you don't understand this perhaps you should read some tutorials?
And I don't understand the point of:
BEGIN { my $var; sub set_var { $var = shift; } sub var { $var; } }
sub; is a compile time statement, so the BEGIN block forces the assignment to happen at compile time also. Also it helps lexically scope $var so nothing else can touch it. Similar to inside out objects.
've had numerous problems trying to determine where a global was changed, and I have a feeling there's a good anti-global argument around here somewhere, but I can't find it. When a script is doing alot of calculating and outputting just the end result, I don't think it matters how localized things are. You still won't know what affected the output.
Let me put it this way and see if it makes more sense. I have a 11,000 line program. It has 10 globals at the top. Because they're global, this means that *any* single one of those 11,000 lines can modify that global value. Therefor, when your global has the *wrong* value, you have problems finding it, because you must examine 11,000 lines of code.

Using properly scoped lexicals, you might have a function that is only 10 lines long with a lexical declared at the top. Now you know only 10 lines total can affect that variable, thus vastly reducing the search space.

Now, you might say, "What if I pass that variable to another function?". In that case, the value in the function you pass from won't be changed, so you don't have to worry about it. The function you pass it to might later change the value, but again you only have that function to examine.

You might also say, "What if I assign the result of a function to my lexical?". In this case, you again have a vastly limited scope to search as you only need to examine any code in that function.

The whole point of lexicals is to reduce the complexity of the code.


Comment on Re^2: Global variable vs passing variable from sub to sub
Select or Download Code
Re^3: Global variable vs passing variable from sub to sub
by kiat (Vicar) on Sep 14, 2004 at 11:16 UTC
    Hi BUU,

    Let me put it this way and see if it makes more sense. I have a 11,000 line program. It has 10 globals at the top. Because they're global, this means that *any* single one of those 11,000 lines can modify that global value. Therefor, when your global has the *wrong* value, you have problems finding it, because you must examine 11,000 lines of code. Using properly scoped lexicals, you might have a function that is only 10 lines long with a lexical declared at the top. Now you know only 10 lines total can affect that variable, thus vastly reducing the search space.
    I think this is an extreme case where globals are used all over the place. Maybe they are cases like that.

    I once had the unfortunate task of tweaking someone's script where not only were the variables global, they were also not declared with my. It was unpleasant, to say the least.

    However, I think there's some justification for selective use of what meryln termed "regional" globals - globals used within a module (if I understood him correctly).

Re^3: Global variable vs passing variable from sub to sub
by Wassercrats on Sep 14, 2004 at 21:32 UTC
    I won't read through the tutorials to learn what that last line does. I recognize all the operators, but can't be sure what it does without looking stuff up. The use of "&&" confuses me. It looks like some boolian structure that I used to know how to use, or maybe it's an ordinary logical "and", but I'd like to see parentheses in that case because I never remember the order of operations of things.

    I recognized the hash, but I'm unsure about the the use of "exists". I guess it's being used for the 1 or 0 value, but I don't think that's how it's usually used. I wouldn't use hashes when teaching something not related to hashes. I've only used them once when I wrote Varstructor, which had to parse code that might contain hashes, and maybe another time for that duplicate elimination trick.

    In the second block of code, I just didn't get the point. Maybe I didn't try hard enough, but a better explanation would have helped.

    No matter what code you use in an example, it helps to explain what it does.

    ...*any* single one of those 11,000 lines can modify that global value. Therefor, when your global has the *wrong* value, you have problems finding it, because you must examine 11,000 lines of code.

    After I posted that reply I realized that might the person's point, but he mentioned having to step through the code with a debugger, which wouldn't be necessary. Is it really so hard to search the code for the variable in question? Even Wordpad, which I'm still using for now, could do that. With globals, you don't have to check to see if you passed the value on to another routine. You merely search for a variable by name.

    As I mentioned in another thread, if you change plans and want to call a variable that was lexically scoped a few routines ago, things get complicated.

    I find the arguments in this thread to be lacking substance. The effort it takes to properly scope variables, which often requires a different code structure, outweighs the problems I've encountered using globals. Globals mean less planning ahead, EASIER debugging, and, using the definition of "safe" that people have used with me, safer code.

      Wassercrats,

      While I agree that debugging code - particularly code that you're still familiar with - is usually just as easy/difficult with or without globals, the Real Reason that I have discovered that people scope things and use 'my' are as follows:

      People use 'my' along with 'use strict' to make sure typos don't get taken seriously. Auto-vivification is cool in some contexts, but I just plain don't see the difference between $options{debug} and $optoins{debug}. Perl does, though, if %options is declared and I have 'use strict' enabled. This has saved me hours of debugging time chasing typos.

      People use local variables in subs because they like to turn them into modules that get used in other programs, and sometimes those other programs already have another variable - used for something else - by the same name. I always use $mib, $sess, $var, $vb, and $vl in my SNMP-related scripts. Straight from the man page for SNMP.pm. This would be a problem if I didn't do a lot of my code in modules (along with 'use strict', 'my', etc. etc.).

      I don't find that having local vs. global variables has helped my debugging any, though (not that I use proper debugging techniques, AFAIK).

      --J

        You said "...I just plain don't see the difference between $options{debug} and $optoins{debug}."

        I've had bugs like that. I don't know what would take more time, debugging such bugs or initializing every variable. The former is rare. The latter would have to be done all the time.

        Luckily, I have VarStructor 1.0 to list all my variables so I could see if I made such a typo. And there is no module that does a better job listing the variables within a script. Diotalevi thought he had a contender, then demerphq thought he had one. Bugs were brought to their attention shortly thereafter. If the only contribution VarStructor 1.0 has made to the Perl community is to highlight the bugs in competing modules, and get them repaired, it was worth it. And now that the bugs are fixed in the competing modules, VarStructor 1.0 STILL kicks their ass.

        I deleted the VarStructor 1.0 code from Perlmonks a few days ago, so I guess you all have one more reason to use strict than I do. This isn't a local variable issue anyway, incase nobody noticed.

        You said "People use local variables in subs because they like to turn them into modules that get used in other programs..."

        I'm not such a people.

      I won't read ...
      Ah, Wassercrats. We know.
      I find the arguments in this thread to be lacking substance

      And then all you provide are arguments like

      The effort it takes to properly scope variables, which often requires a different code structure, outweighs the problems I've encountered using globals.

      with no explanation whatsoever about what you find so difficult about scoping variables.


      I'll summarize everyone else's arguments into a form which contains the same amount of "substance" (You keep using that word... I do not think it means what you think it means--Inigo Montoya) as your posts: Scoping variables takes no additional effort and it eliminates one potential source of bugs.

        Who are you?

        merlyn said "Both 'passing around' and 'global variables' are a signs of a misdesign....provide a higher-level interface that don't need to expose that variable...create a module..."

        That sounds like a script using local variables might require a different structure. Obviously, scoping a variable to a certain block means it shouldn't be needed outside that block (or "region"), and that takes more planning, and some luck.

        Another obvious bit of effort comes from declaring variables, and even by using "my".

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://390780]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (5)
As of 2014-11-28 04:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (193 votes), past polls