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