in reply to Global variable vs passing variable from sub to sub

Yeah, that's right. I'm back, and I have something to say. This is really a reply to people who've given code examples in this thread.

I don't understand the last line of:

sub account_over_limit { my ($account, $balance) = @_; return exists $LIMITED_ACCOUNTS{$account} && $balance > $LIMIT; }
And I don't understand the point of:

BEGIN { my $var; sub set_var { $var = shift; } sub var { $var; } }

I'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.

Another, barely related thing--I'm just about done with a GNU tar GUI for Windows, and I'm finding good uses for goto all over the place.

Anyway, please make your code examples as simple as possible and explain them properly.

Replies are listed 'Best First'.
Re^2: Global variable vs passing variable from sub to sub
by BUU (Prior) on Sep 14, 2004 at 10:10 UTC
    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.
      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).

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re^2: Global variable vs passing variable from sub to sub
by Anonymous Monk on Sep 14, 2004 at 19:41 UTC
    This has already been covered in other posts, but this may clarify things for Wassercrats.

    If you don't scope your variables, it is not immediately obvious whether:
    1) You variables will have changed by calling a sub.
    2) If the variables did change, whether they were changed on purpose, or accidently.

    $x = 0; DoStuffX(); print "As long as no one used global variables, I know that x = 0 ", "without needing to know what DoStuffX does.\n"; if ($x != 0) { print "Nope, I need to spend time looking through ", "DoStuffX to find out why x changed. I really ", "wish the guy used \$x=DoStuffX(\$x) so that I ", "would know whether he changed x intensionally ", "or not.\n\n" }; $y = 0; DoStuffY($y); print "As long as no one used global variables, I know that y = 0 ", "without needing to know what DoStuffY does.\n"; if ($y == 0) { print "Yippie! I can go home early!\n\n" }; sub DoStuffX { # lost of code involving $x $x=$x+1; # lots of code involving $x }; sub DoStuffY { my $y = shift @_; # lost of code involving $y $y=$y+1; # lots of code involving $y };