Re: Global = root of all evil
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Nov 02, 2006
- 595 views
On Wed, 01 Nov 2006 17:53:37 -0500, Euman <Euman at triad.rr.com> wrote: >Hi all, > >Global vars, funcs, procs, etc.. root of all evil?? > >more so in C but in Euphoria as well.. > >Any takers?? > >personally I'm making sure my habits of using global's >extinct..for the most part.. It is not a bad idea to perform a global search for "global" as part of source code cleanup. Global constants and routines are a bit of a necessity. If your results are something like:
eaclip.ew:17 global function copyTextToClipboard(sequence lines) eaclip.ew:66 global function getTextFromClipboard() eaclip.ew:116 global function isClip()
Then you can be pretty sure it will not cause you much grief, even:
global integer cbX, cbY global procedure ctrlBracket(integer direction) -- -- process ctrl [ and ctrl ]. -- jump to matching [end] procedure/function/type/for/while; -- cycle fwd/back through if/{elsif}/else/endif; -- jump to matching [,], (,), {,}. -- -- direction is -1 for backward, +1 for normal forward, or -- 0 for forward skipping elsif/else. (fold handling) -- -- Result in cbX, cbY cbX=CursorX cbY=CursorY
is not too bad, as cbX, cbY are only meaningful after a call to ctrlBracket, and hence it does not matter if you overwrite them in some other random place, whereas:
easynld.e:9 global sequence Extensions, -- eg {"e","ex","exw"} easynld.e:12 global integer newSyntax -- ExtensionNo, or 1=none easynld.e:15 global sequence SynNames, -- eg "Euphoria" easynld.e:30 global integer MAXnColours easynld.e:56 global sequence wordChar -- set by easynld.e easynld.e:59 global sequence standardColourNames,standardColours easynld.e:96 global sequence comment -- eg "--" -- set by changeTo() easynld.e:97 global sequence blockComment -- "" easynld.e:98 global sequence ColourTab -- "" easynld.e:99 global sequence StyleTab -- "" easynld.e:103 global sequence charMap -- set by changeTo() easynld.e:105 global sequence urlChar -- all are TokenChar easynld.e:706 global procedure initSyn() easynld.e:773 global sequence sampleBrush, easynld.e:782 global atom backBrush easynld.e:784 global atom wwrapPen easynld.e:786 global function reBrush(sequence cnew, sequence cold) }}} <eucode> Then it is immediately obvious there is much more scope for trashing something vital elsewhere and maybe you should rethink that code. The routine interfaces can also be far harder, as you may be expected to set a global variable correctly before calling (actually also true of CtrlBracket above). Ensuring that any global variables you need have well-thought-out names that are unlikely to be accidentally re-used elsewhere is one way of reducing the risks. One half-baked idea I have is 'global-constant-local-variable's, ie you can legally modify them within the source they are defined, but get compiler errors if attempting to modify them anywhere else. Not exactly sure how to specify that though, how does: }}} <eucode> global constant udt myTable, myList
(where udt could be integer, boolean, seq8 etc) sound? It would not be legacy compatible though, currently the "global constant udt" part would define a new variable even if a valid [global] type udt exists, and any similar legacy code would cause a compile error when run on a newer version of Eu. A more compatible idea is:
glocal udt myTable,myList
which gets my vote, but "glocal" is admittedly a bit odd. Of course you can stick with the local var + global get()[/set()] method. One last thing I will say is that forward routine references can cause headaches enough, imo allowing forward references to [global] constants and variables would really damage the elegance of the language (and probably treble compile times). I assume you had an "episode" which triggered this thread, care to share? Regards, Pete