PreviousNext…

Repeat after me...

Global variables and objects suck!

Oh, I thought I'd come up with a legit. scenario for declaring a couple of global string variables in some Lotusscript I've been working on. How wrong I was. Bad move, very very bad. I should have stuck with my original theory, that one should never use the buggers1. I'm not being a total stick in the mud, others seem to agree with me. For example, Andrew Pollack, who gave a very good talk on advanced Lotusscript techniques and approaches at The VIEW's techie conference in Amsterdam last October. In fact, whilst I'm on about this, here's a link to his presentation: Advanced Lotusscript - Performance & Reusability

The whys and wherefores of this dogmatic stance of mine I have also covered as part of a longer draft I sent to e-Pro magazine back in April. I don't know if that will see the light of day as an article though, so maybe I'll ask if I can reproduce it here someday.

Anyway, back to the code. Ironically, these particular string variables were supposed to help me identify erroneous code. I was using them to track Lsi_info details within a scheduled agent linked to two script libraries (containing thirteen separate routines between them). Much scope for calamity I'm sure you'll agree, and by jiminy I hit it: how can you possibly debug iffy code when your NotesLog doesn't even come close to reflecting reality (i.e. not giving the correct name of the buggy routines). Gah! I'm such a doofus. Keep your scope as tight as possible I say, unless you have a brain the size of Mars to remember everything that's changing.

Tchcoh. So, please feel free to weigh in with your own tales of silliness, if only to make me feel better.

A belated happy 4th to my readers in the US of A, and to everyone else, a good weekend!

1 - OK, disclaimer. I have been known to use globals for standard error messages / UI text and such. But they're always expressed as constants, so that's low-risk eh!

Comments

  1. Hi Ben, thanks again for the link and the kind words. I know of very few acceptable uses for global variables. Every time someone tries to proove another one, I almost always can show them another way. They make debugging seriously ugly.Andrew Pollack#
  2. I'm not sure whether many people make a distinction between modular (shared within a library) and global variables. There are a lot more cases where modulars are reasonable - the art is to know when a good modular (and very very occasionally, global) variable will do the trick :-) We often use modular variables for things like NotesSession, the current database, a consistent 'now' value for use by scripts, and so on. In much bigger agents, declaring this globally can also be useful. These sorts of 'read-only' variables have their place, it's when you're using modulars/globals as a shortcut for passing specific, non-general data between routines that things can go wrong.

    We have pretty strict rules about naming modulars/globals (all modulars are prefixed with an m, all globals with a g), how we declare them (together, in a clearly commented section close to the top of the Declarations section), whether there's _any_ chance that a library will ever be 'reusable' in another context where reliance on globals would break (eg. classes never rely on globals, they init with passed arguments), and apart from some of the 'common' modulars where experience has proven them safe, we encourage long, long, hard thinks before making anything else modular/global.

    We have reams more 'standards' (some rather unorthodox) regarding things like scope of constants, public/private routines, and so on, but in general I agree with you - the scope should always be as narrow as possible.

    (and yes, most of this has been the result of very painful experience :-)Colin Pretorius#
  3. Agreed - to a point. To me, anything that prevents you from cutting a fuction or sub from one script/agent/library and dropping it into another intact without worry about it needing anything external to function, should be avoided.Andrew Pollack#
  4. That's really what it's about for me… the odd thing is, I designed much of the code to be truly modular: I can pick it up and dump it elsewhere without worrying about dependencies and so forth.

    So why I did this with the three string vars I don't know. It must have been a bad morning / low coffee rations ;-) Ben Poole#
  5. Andrew, I take your point, I think it really boils down to knowing when a routine could be 'general' and shouldn't rely on external help, and when it's so tightly coupled to a specific task or agent, that using it outside of that context calls for some serious analysis of what it does anyway. I think it boils down to the old maxim of designing for the general case (and conversely deciding when generality hampers the design).

    As an aside, I really don't like cutting/pasting routines, and hardly ever do it. The occasional once-off agent might make sense, but 9 times out of 10 it's likely to become a maintenance nightmare (hmm, does this agent use the foo() before Joe added the frob fix?) I prefer for the routine to be moved to helper libraries anyway - where the interface and behaviour is clearly documented, by its nature globals/modulars won't be used, and the process of making it more 'public' means that it's been (re)designed for generality anyway.Colin Pretorius#
  6. Colin, I think we're in complete agreement on all points. I would love to describe my perfect utility library toolkits -- and how I've gone to D6 now with a single design element in a central design template to hold it.

    I'd be full of b.s. though -- much as I'd like to, I've never actually assembled all those helper functions into a single library.

    Oh well. Its a case of the cobbler's kids having no shoes I think.Andrew Pollack#
  7. Hey Ben,
    I just did a google search on "Tchcoh" and it returned me 2 hits, one to this site and one to macfora.com, to a post written by you! Don't you think you owe it to your many avid readers to do one of your funky popup definitions for this (IMHO) underused expression :-)

    (looking forward to a few pints with you on Thursday!)Spikey#
  8. No mate, let's leave them in suspenders… ;-)

    (HINT: "Gah" has become my ejaculation of choice over "Tchcoh" but the latter still holds a place in my heart).Ben Poole#
  9. Colin (2), I agree, somewhat. I have gotten to the point where I don't even use it for that, except for the aforementioned constants for error msgs and such. For instance, even when you dim NotesSession over and over, you are still getting a handle to the same session in memory (IOW you're not creating new session objects in memory). So, it really makes the code more complex (IMHO) to try to globalize NotesSession (same thing applies with NotesUIWorkspace).

    For the other things (current db, etc.) I generally decare it for the current scope only. If I need to "do" something to it, then I delcare it in the "hosting" code (such as the Initialize of the agent), and then pass it as a parameter on the function/sub. Same thing applies for "new" values that the function produces - I always pass an "empty" var in as a param, and get the value back from the function on that var. Functions always return error codes themselves, and pass values/objects in and out on the parameters.

    So, I am like the rest of the folks here - Globals are in the same ilk as GOTO ;)

    RockRock#
  10. You're definitely going to appear in print in e-Pro Magazine! We got a bit of a backlog of articles going on at the moment that we're trying to work through, but you're on the lineup -- you wrote a great article!
    LibbySheepish Libby#
  11. :-D Cheers Libby!Ben Poole#
  12. I suspect that in 5 years' time I'm going to be at a job interview and someone's going to say 'I saw what you wrote about globals' and regret posting ;-)

    I agree with the rules, I've also been burned by the kind of thing that happened to Ben - I think I'm just a bit more comfortable about breaking them in certain (limited) situations. What gives me more confidence about it is making sure that if I do, it's documented so that other coders know what I've done, and won't have any nasty surprises or head-scratchers induced by what I've done. I think working in a company with a single batch of apps and standards makes this easier. If I was doing a consulting gig, I wouldn't have that 'familiarity' luxury and would steer clear.

    As for gotos, no arguments from me there. Then again, Dijkstra also said that anthropomorphising computers is a sign of professional immaturity, but if you can't say things like 'compile, you *%$#@!' then what's the point?Colin Pretorius#
  13. thanks for posting that Rock.

    you, er, rock!

    btw, THAT is the kind of stuff we need in best practices sessions. things that the help just doesn't tell you (or does it?), that the notessession is the same one whether you declare 8 times or once.jonvon#
  14. (13) - jonvon, spot on. Everyone learns from those kinds of sessions, no matter how hoary a Notes developer they might be ;-)

    (12) … as for you Colin, LOL ! You've made some great points that brook little argument. Your bit about anthropomorphising computers is hilarious: how many times do I say "Oooh, you fu&*!er" to my StinkPad in one day? Scary.

    Bad coder, BAD coder…Ben Poole#
  15. I suspect that in 5 years' time I'm going to be at a job interview and someone's going to say 'I saw what you wrote about globals' and regret posting
    Almost forgot: Colin, do you seriously reckon personnel, sorry, human resources capital people read this webular travesty? My God, I hope not. ;-)

    He Who Shall Never Be Employed AgainBen Poole#
  16. I'd always figured NotesSession was shared (LS hooks into a C API's session etc, doesn't it?), but I was always scared that there'd be a 'system call' overhead creating the window into the LS 'VM' (or whatever it should be called). Got me worried that in one of those famous 10,000 document agents, recreating NotesSession would be a serious inefficiency.

    Lies, damned lies, and benchmarks, and all that, so I finally got around to testing it. I dimmed new NotesSessions inside two routines inside an otherwise empty loop, and timed it. I can now confidently say that this halved the execution time - but over 10,000 iterations this meant from 120k loops per second it dropped to 60k loops/sec. Which I'm sure I could live with :-)

    Rock, you may have converted me on the NotesSession thing… and jonvon, I agree - there are always a zillion 'under the hood' things you worry about - the normal how-to literature doesn't always fill in these blanks, and it's great to know how things *really* work.Colin Pretorius#
  17. Ben (14) - my favourite term in the jargon file is this one :-)

    I also stumbled across this Dijkstra quote on another blog recently: "It is practically impossible to teach good programming style to students that have had prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."

    Erk, where did LS come from, again? After a few years of trying to build classes in LS, I can kinda see what the man was getting at…

    As for (15), I'm lucky that right now I'm the one who'd be doing the hiring, and I'll quite confidently say that I wouldn't hire anyone who doesn't regularly visit sites like yours, notestips, lotusgeek, codestore etc. I think there are precious few Notesers in South Africa who spread their research beyond the likes of LDD/notes.net, if that much. At least not in my experience [smiley frown]Colin Pretorius#
  18. I like that that bit o' jargon!

    I've heard that particular Djikstra quote before: whilst he kind of had a point (!), the man was clearly too enamoured of punchcard programmers, may he rest in peace… (I speak as someone who has a whole book on that very subject. Let's not go there).

    Thanks for the kind words re this and the other sites out there. Speaking for myself, I try :-D Ben Poole#
  19. Ah, yes, the good old days, when men were men and valve tubes were nervous! ;-)Colin Pretorius#
  20. Hey, another one you may as well work with globally, are file numbers and file handles. They exist outofbounds, and also some (many) lsx based objects.
    Andrew Pollack#
  21. i'd just like to say that Colin Pretorius must be the coolest name i've ever seen. are you sure you aren't a movie star or something? i am so not being sarcastic. freaking cool man.

    :-)jonvon#
  22. Hey, thanks jonvon. I'd like to take the credit but it was really my parents and my ancestors' doing :-)Colin Pretorius#
  23. Ben, I agree - we need to look at adding some new content to the BP sessions regarding "higher level" concepts, especially in LotusScript. Maybe I should start a blog entry asking for stuff that should be covered in an "Advanced Techniques" class - things like what we've been talking about here, working with files (Andrew's post brought that up), and so on. It could be a pretty interesting session…

    And I'm with jonvon - that is a friggin' kewl name. Sounds like a Roman senator, or gladiator ;)

    That's it! Colin is a CODE GLADIATOR.
    (/me pounds fist in chest and says, "Hail Ceasar!")

    Hmmm, codegladiator.com would make a KEWL blog name :) You get first dibs Colin…

    RockRock#
  24. Oh yeah, thanks for listing LotusGeek in that list - I am honored :)

    RockRock#
  25. Gawd, you guys are making me blush :-)

    Thanks for the dibs, Rock, but the problem with being a gladiator is that eventually someone's going to come along and lop your head off :-) (But I'm rather amazed that nobody's nabbed that domain in any form yet, it's a cool name)

    And I do mean it regarding your sites (Rock, Ben) -- I have serious respect for the effort you and others expend and expertise you share. It goes back to treating one's profession as a craft, going beyond a pay cheque, or even being 'good' (iow 'just good enough') at what you do. You help people who will always want to be better at what they do, who want to advance their 'craft' - by sharing your experiences and thoughts, and by fostering a self-selecting community of people who seek out these communities because they share the mindset.

    Bluntly put, someone who doesn't approach development in that way, isn't someone I'd enjoy working with (speaking from experience, here), OR entrust our company's systems to…Colin Pretorius#

Comments on this post are now closed.

About

I’m a software architect / developer / general IT wrangler specialising in web, mobile web and middleware using things like node.js, Java, C#, PHP, HTML5 and more.

Best described as a simpleton, but kindly. You can read more here.

";