Python's BNF

Steve Holden steve at holdenweb.com
Fri Feb 29 09:26:41 EST 2008


MartinRinehart at gmail.com wrote:
> Gabriel and Steve,
> 
> Poor globals! They take such a beating and they really don't deserve
> it.
> 
> The use of globals was deprecated, if memory serves, during the
> structured design craze. Using globals is now considered bad practice,
> but it's considered bad practice for reasons that don't stand close
> scrutiny, this being a perfect example.
> 
Times move on, but some ideas remain bad ideas, and the *uncontrolled* 
used of globals is exactly one such bad idea. You seem to believe that 
the tenets of structured programming have been deprecated, but in fact 
they have been incorporated into the mainstream.

>     ofile = ...
> 
> # global
> writeHTML()
> def writeHTML():
>     ofile.write( .. )
>     writeBody()
> def writeBody():
>     ofile.write( ... )
>     writeEntries()
> def writeEntries()
>     ofile.write( ... )
>     writeEntry()
> def writeEntry():
>     ofile.write( ... )
> ...
> 
> # "fixed" to eliminate the evil global
> writeHTML(ofile)
> def writeHTML(ofile):
>     ofile.write( .. )
>     writeBody(ofile)
> def writeBody(ofile):
>     ofile.write( ... )
>     writeEntries(ofile)
> def writeEntries(ofile)
>     ofile.write( ... )
>     writeEntry(ofile)
> def writeEntry(ofile):
>     ofile.write( ... )
> ...
> # repeat above for another half dozen subs that also use ofile
> 
> The code's simpler before the fix.
> 
It's also more error-prone and more difficult to read. But since you 
should probably be encapsulating all this into an HTMLWriter object 
class anyway I suppose there's no point trying to convince you any 
further. See below for a point that *might* (just possibly) change your 
mind, though.

> So, as a nod to the anti-global school of thought, I changed 'ofile'
> to 'OFILE' so that it would at least look like a global constant. Then
> I changed to '_OFILE' as a reminder that this is a modular, not
> global, constant. Ditto for '_PRODUCTIONS'. Modular constants share
> exactly none of the coupling problems that globals can have. You'll
> let me use modular constants, right?

Nope. You are changing the form without changing the substance, so my 
objections still stand. Your code makes the assumption that nobody else 
will ever want to reuse it, and by doing so almost guarantees that 
nobody will. The principles of modularity are there for a reason, and 
while I can admit I have written similar programs myself as quick 
throwaways I would never dream of promoting them as examples of sound 
practice. I can't believe I am going to have to mention "coupling" and 
"coherence" as useful design principles yet again.

One final issue: in cases where your functions and methods do 
significant work, the ofile argument is passed into the local namespace 
of the function or method. This means that no late-binding name lookup 
need be performed, which represents a substantial improvement in 
execution speed in the event there are many uses of the same global.

Or perhaps you would rather "optimize" that by writing

ofile = ...
writeHTML()
def writeHTML():
     global ofile
     my_ofile = ofile
     my_ofile.write( .. )
     writeBody()

I wish you'd stop trying to defend this code and simply admit that it's 
just a throwaway program to which no real significance should be 
attached. *Then* I'll leave you alone ;-)

regards
  Steve
-- 
Steve Holden        +1 571 484 6266   +1 800 494 3119
Holden Web LLC              http://www.holdenweb.com/




More information about the Python-list mailing list