in reply to Avoiding global object handle

I don't quite see the point in having a global function instead of a global variable. To me it makes more sense to have a global variable since that needs to be declared. If you have a subroutine that you think you can remove you won't find out that it perhaps was needed until the program dies because the subroutine was missing in some obscure corner of the program. However, you'll instantly know if the variable is missing. Furthermore, if you use our() you'll get a warning if you don't use the variable. Example:
sub make_handle { ... } our $handle = make_handle(); # "... used only once"
So I consider globals a good thing when they're proper to use. One can argue that using a variable like this (and still keep the 'used only once' warning) will require you to always setup the handle. But if it's a large application and the handle will almost always be used then I see no reason not to initialize it right away.

I also believe it's faster to use a variable than to perform a sub call. But if you still want to use a sub call and really really care about performance, you might want to try a hack like this:
sub foo { my $foo = shift; return undef unless defined $foo; no warnings 'redefine'; *foo = sub { $foo }; foo(); } { my $bar; sub bar { defined $bar ? $bar : ($bar = shift); } }
&foo and &bar are analogous. But &foo runs faster, at least according my benchmark.

Cheers,
-Anomo

Replies are listed 'Best First'.
Re(2): Avoiding global object handle
by FoxtrotUniform (Prior) on Mar 26, 2002 at 17:23 UTC
      I don't quite see the point in having a global function instead of a global variable. To me it makes more sense to have a global variable since that needs to be declared.

    Accessing the global handle through a subroutine makes it much harder to accidentally clobber it. (Further, it makes clear to anyone reading your code that $handle has a well-defined value that doesn't change, which is kind of nice for maintenance programmers.)

    In general, I'm a big fan of wrapping related scope-specific variables in a singleton class, just because it makes domain control so much easier. This works best in very specific cases, where you don't see much potential for partial code reuse, because you're coupling all the code that depends on the singleton. It becomes correspondingly harder to pull out individual functions from that scope and use them elsewhere, because you have to pull out the singleton as well (which probably doesn't fit your new problem perfectly). In Biker's situation, this might be a good fit.

    --
    :wq

      I'm speaking, of course, of when it's best fit to use a variable/subroutine instead of some other technique.

      Accessing the global handle through a subroutine makes it much harder to accidentally clobber it.

      True. I didn't think of that, especially since he uses it as foo()->bar, and it's hard to modify it that way. I don't think there's a high risk of accidently modifying this particular variable, but I see your objection.

      (Further, it makes clear to anyone reading your code that $handle has a well-defined value that doesn't change, which is kind of nice for maintenance programmers.)

      By convention you name those variables in upper-case, so in this case it would be $HANDLE instead. There should be no larger question marks regarding that issue.

      I think that the small risk of clobbering the variable is out-matched by the warning feature of variables. It helps to keep code clean, and that is something maintainers also appreciate. I hate seeing unused subs/variables just because the author was too afraid/paranoid to remove them.

      Cheers,
      -Anomo
Re:x2 Avoiding global object handle
by grinder (Bishop) on Mar 27, 2002 at 09:17 UTC
    I don't quite see the point in having a global function instead of a global variable

    One thing it does buy you is the ability to drop a breakpoint on it in the debugger, and then play with caller to see where you were called from. That is not quite as simple to do with a variable.

    In a farfetched scenario, you could also diddle the package's symbol table to wrap or replace the function itself. That's much harder to do with a variable.


    print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'