You have really asked a number of questions here. I can’t speak from any platform of expertise that speaks to the internals of LotusScript or programming standards in general. I am a cowboy programmer. My approach is to go with what works. So here are the questions that sprang forth from your example and some of my armchair commentary:
Is it better to instantiate each object using its own reference variable down a “tree” of objects or to chain them together? Chaining them makes it harder to read and debug code. Chaining is fine if this is a one-time deal. But if you do repeat operations to any of the objects along the way (e.g. read multiple values from the backend document in your case), then you should instantiate the object formally.
The assumption here is that you are writing front-end code in the context of the current document in front of the user. Which makes me wonder if you really need to get a handle on the backend document object to read a value, when you could read it off of the UIDocument.FieldGetText. Just checking. (and as was mentioned by another poster, your UIDoc object would most likely be instantiated with the CurrentDocument property in NotesUIWorkspace)
Your example assumes that there is an item named “Value” in the backend document. In most cases, using the extended syntax would put the item name here. (I’ll presume that you were just using “Value” as an example!). But just to be clear there is no .Value property of the NotesDocument class. And I would be nervous about using such an item name, as you could have problems later if the property is ever added, or you are using JavaScript, which does have a Value property.
Whether or not you should use the extended syntax (doc.value) versus the GetItemValue/ReplaceItemValue methods. Though it is quick and easy (I use it all the time), the extended syntax doesn’t work with COM (or Java?) (you can’t use UI classes with COM/Java, but that is a different matter). Also, GetItemValue is more portable in that you can use a variable as the field parameter (whereas the extended class hardcodes the field name). So writing reusable functions where you pass a field name won’t work as well when using the extended class. Also, if you want to set the IsSummary property, you need the NotesItem object, which is returned by ReplaceItemValue (if you had set the value using the extended syntax, you would have to instantiate the item object anyway). So you may as well bite the bullet and instantiate the item and perform multiple operations on it (set value, issummary, isauthors, etc.) Oops, I just looped back to 1)
By the way, you would probably want to declare the variable “Value”.
I would agree with all this, but emphsize one point. If you step through the debugger (and this is because it is not a great debugger as much as anything else), it will be a heck of a lot easier to find problems if you don’t use the chained:
UIDoc.Document.Value
For this reason alone, I almost always separate out the statements:
Set doc = UIDoc.Document
Value = doc.Value
Also, always, always, always use Option Declare. Make sure it is set by default, since Notes 6 lets you do that. It will save more trouble than any other standards you can think of.
The reason I have asked these questions is that I have just inherited a system where the developers have never heard of Option Declare and usually do the chains.
I am finding it confusing as hell trying to read the code (comments I hear you ask, they are few and far between)
Notes 6 sets it as default? Where can I do that? Mind you, I dare not put that in this system, I have noticed many instances where things aren’t declared at all.
You set this as a new option in the infobox/properties box for the Programmers pane, 2nd tab "Automatically add ‘Option Declare’. (Note that this works for newly created design elements only, existing code won’t be touched).
I’d add the Option Declare statement right away to each module and fix/compile/fix/compile until it saves cleanly. Otherwise you have timebombs in your code, ready to explode at any time.
PS: I entirely agree with Ben’s reason to not use chaining because its easier in the debugger. Another reason is that chaining doesn’t allow to test if objects are valid. Sometimes objects can be NOTHING and need to be tested for this, which is impossible via chaining.
I see a lot of code that is not mine, since I handle support calls for our Midas Rich Text LSX. When I get a script without the Option Declare set, even though the customer is claiming whatever problem they are having is with Midas, I figure I have about a 50% chance of fixing the problem by setting the Option Declare and going through the pain of declaring and checking the errors. When this happens, I always let the customer see what really fixed the problem, because it is good business to support your customers (and because it might convince them to use Option Declare and not cause me needless support calls in the future).
I guess my point is, go ahead and turn it on and deal with the pain once. It will be worth it in the long run. You might even be surprised by the problems you fix in the short term.
Some people seem to believe that it is better to code everything in the longest possible way, and include as much redundant information as possible. Not, for example:Value = doc.Value
but something like:
Let IBM_lotusscript_variant_array_Value = IBM_lotusscript_notesdocument_object_doc.lotusnotes_field_Value
Even this can be “improved” by getting a NotesItem object first and using its Values property.
In my experience, code is fastest and cheapest to develop, and easiest to maintain, when it is written as simply as possible and contains little redundant information. But fast, cheap and easy does not always suit managers who have budgets to maximize. So all kinds of “standards” are imposed to slow things down and increase costs.
By the way, both versions of your code will fail because UIDoc is Nothing
Without getting into huge philosophical debates about language and structure, Hungarian prefixes, and all that, the only thing I would add is that in your context, “fast cheap and mantainable” usually means for that developer. I have inherited reams of code over the years, and the easiest stuff to comprehend and therefore usefully maintain was the stuff that used our organisation’s standards: I didn’t have to learn that developer’s “dialect”.
But overall I take your point, and I’m inconsistent, 'cause I used prefixes in my Lotusscript code, but not necessarily in my Java
The first example is one way of extracting a field value from a back-end NotesDocument, versus the second technique of accessing the front-end document. Both methods have their pitfalls, and it all depends on (a) what it is you’re trying to do and (b) where you’re doing it (i.e., context).
Personally I don’t access field in the UI doc that often, although there can be times when one does (e.g. basic onSubmit / Querysave validation and the like).
How you access fields in the back-end depends on what it is you’re trying to do. You can use the technique you describe, but you can also delve into the NotesItem class, use extended syntax like NotesDocument.FieldName(0), and so on. It’s not so much a question of “best practice” but what it is you’re trying to do. Sure, some methods have more of a performance boost, but you’d have to be doing some major work to actually discern a difference in this regard. I prefer to do something like this –
Dim doc As NotesDocument
Dim strValue As String
Const FIELD_NAME = “txtATextField”
’ // … set doc …
strValue = doc.GetItemValue(FIELD_NAME)(0)
– because field names often change, and this can be easier to maintain than:
I think that keeping code as simple as possible is the best solution. If you look at an average application, you spend most of your time in maintenance. Since we cannot control who will be maintaining the code next or at what skill level that programmer will have, keeping things simple avoids any confusion as to what the code is doing. Sure it may be slick but if it takes a person a few minutes to try and understand what is happening, then write it simpler.
Having said that, of course there is a trade off with performance. You do not want to write code that will also give a huge performance hit either. In your case, I would have to ask the following:
Are you going to access the backend document somewhere else in your code
Are you going to access the value of document somewhere else in your code
If 1. is yes, then i would dim the backend document and set it as you did in the first example. Why? Each time that you refernce the object uidoc.document, Domino has to do some thinking to get at the document. If you dim the document, you do it once and that is it. Domino does not have to do any more thinking to get at the document.
If 2. is yes, the same applies. If you store the value of the document in a variable, you only have to perform the code to get at the variable once saving cpu time (I know, it is just a little).
Personally I rarely use the UIDoc to get at the document but the same priciples apply.