I did a search on a few keywords and didnt find an open discussion on this (thought I may have missed it)....
I have a fear this post might create a war between some of you hard core buffs who have a fixed way of doing things. One of the things with Navision is that there are many RIGHT ways of doing things, but this means many programmers consider their way 'MORE' right.

But lets risk it hehee.
However I would appreciate an open discussion on the topic of when and where to use or not use Global and Local variables. What are the advantages and disadvantages of each. I know Java programmers and the like will always say "Use local whenever possible, at all times, and only go global when you have to" but this is born of seeing each object as a 'Class' and the Java created fear that a global variable in a class is visible outside the class.
Purely in Navision however what are your opinions on Best Practise. What are the reasons for this. And why etc. How would your opinions on this differ from each object type.... for example most Variables you declare in a Report cant be local because in a lot of cases after the code is processed you need to display a lot of these Variables in the printed out section. So a local variable in OnAfterGetRecord() can't then be directly printed in Body() etc etc.
And when it comes to best practises for upgrading, from 3.6 up or from 4 to 5.1 etc, how would the two types affect anything?
I turn it over for discussion......
Comments
My idea is :
-functions/procedures : they should only comunicate with the rest of the program through their parameters. So this means all their variables should be local. The exception I make is for text constants. I always put those as globals because it is easier to control those. And after all : they are constants.
-variables used in triggers : I always put them as globals because in general they need to be used in other triggers. And it is easier to work with them when they are globals.
-For upgrading : if you put extra code in existing objects, use a function in which you put your extra code and call the function. This way the merge tool (e.g. Navision Developer Toolkit) for upgrading has less problems recognizing the new code.
No PM,please use the forum. || May the <SOLVED>-attribute be in your title!
And to the large extent I do agree with kirki... =D>
For any queries you can also visit my blog site: http://msnavarena.blogspot.com/
If the variable is only useful for the trigger you are in, use local. If the variable is useful outside the scope of your current trigger, use global.
I've started doing the 'everything has to be local' thing a while ago, and found myself creating the same variables multiple times in the same objects, so I stopped doing that.
Now I try to use parameters, that is the only way to really control what you do. Pass the SalesHeader by ref (check the VAR box) into the function and you're working on the same variable.
RIS Plus, LLC
Codeunits i use only local except Text Constants. I try to create functions for more then just 1 call
Reports, Forms, Dataports i use global just because i have a better overviw
Dodga
This is also how I do it.
I guess you posted in the wrong forum, I think this post was referring to Navision
We know that its an ERP and not a development environment, but I really do not understand how and why they sometimes like to do the opposite of basic good practice, no matter what the environment or language being used. Some of the standard code is shocking. Take the OnRun trigger of Codeunit 80, it's almost 1900 lines long. Who the hell designed and wrote that in such a manner? The object has around 130 members (global variables)! :shock:
Not to mention that the level of documentation at the code level is nil. If the blokes working on Windows (what am I saying - it's bloatware) or the NAV client programmed in such a manner , they would be out on their arses faster than you could say Vista.
It's crazy.
I can sign under what you wrote... :whistle:
It is what I am doing too.
MVP - Dynamics NAV
My BLOG
NAVERTICA a.s.
No PM,please use the forum. || May the <SOLVED>-attribute be in your title!
RIS Plus, LLC
I've seen it countless times people adding code to objects, lines and lines of it, sometimes not even commenting it, sometimes changing or even deleting standard code instead of commenting it out and calling a new function with the new code in. Most developers will go straight to the globals and add new variables without any thought at all - design doesn't exist in Navision most of the time. It ends up making a mess over time, and it only gets more and more messy. The argument is that Navision is an ERP that allows for rapid development. True, a GOTO can help with that as well, but we don't want that to rear its ugly head again do we? RAD is all well and good, but it was originally proposed for building prototypes that help to gain end client requirements, and then would form the basis for the real implementation, not for the willy nilly throwing together of solutions. Yes, it might be quicker and cost less in the initial development stage, but developing any type of production software in such away will inevitably increase (amost exponentially) development costs and time during the lifetime of the system.
My original point remains, you don't use a global variable in case it might be useful and save you time. They should only be used to represent a property or state of the object or to provide control information that cannot be passed as function/procedure arguments in all cases. Making variables global because it proves useful or makes your life easier is seriously bad practice. What if someone else comes along say a year later, adds a new function/procedure that uses this variable, yet there is a bug in this new function that puts the wrong value in the variable. Then, the original bug free functions using go totally wrong or start doing strange things because another function had changed their data in some wrong way? It seriously doesn't take much for this to happen in a complex object.
Pass arguments around when you can. If not, in the case of forms for example, encapsulate them inside a codeunit with mirror access functions, and pass that around. Only use globals as the last resort. You should also only pass variables by reference if the functions it is sent to are meant to modify it in some way for return to the calling function, or for speed, or in cases where you really do need the same instance.
Also remember coupling, there is absolutely no need to send 19 arguments to a function like someone was asking the other day. 8 is pushing it (yes I know we have no compound variable types other than temporary tables), if it gets over ten you really need to start thinking about doing it in a better way.
Text constants are different, as they are, well, constants. Just don't name them Text001 etc. Give them a meaningful name.
Don't make functions/procedures longer than 50 lines of data touching code.
Also, document your code in a reasonable manner, no not every line, no need to be excessive, but at least a basic function synopsis at the top of the function, a line comment at the top of every main block, and a change log in the documentation trigger.
I work mostly the same way as well and I suspect all the developers in NAV works the same way. All rules and formalities aside, it makes perfect logical sense in the Navision development environment.
It's also easier to copy a function to another database if the variables you created in the function are all local.
AP Commerce, Inc. = where I work
Getting Started with Dynamics NAV 2013 Application Development = my book
Implementing Microsoft Dynamics NAV - 3rd Edition = my 2nd book
Design doesn't exist? Dude that's not a very nice thing to say :-k you can talk all you want about how the software works or how well written it is, but you can't just sweep it onto a heap and call it 'without design'.
Add development cost? C/AL is easier to develop in than any other IDE out there, by a factor of at least 50, maybe 100. I would bet a large sum of money that any team of good NAV people will beat any team of C# people in developing a piece of business functionality. The thing is though... because it is so easy, there's a lot of hack jobs out there, and because this world is so small, they stand out easily. You look at all your C# jobs out there and I will bet that there is relatively speaking more crud out there. You just don't see it because there is so much of it.
Making life easier is seriously bad practice??? :-k :shock: I'll just leave it at that
RIS Plus, LLC
M - Miklos
T - Tiger
C - ?
That would really defeat the purpose of having this community in the first place.
AP Commerce, Inc. = where I work
Getting Started with Dynamics NAV 2013 Application Development = my book
Implementing Microsoft Dynamics NAV - 3rd Edition = my 2nd book
You can tell when someone is joking when there's a smiley in there, like this
RIS Plus, LLC
Firstly, you can write crap in any language, some make it easier to do so than others depending upon what systems they are embedded into. What Navision does is actually allows you to change the nucleus of the system. WHAT? It's a very old concept that has never changed with Navision, they simply have not even tried to hide anything. But when you have 2000 functions in a codeunit with 130 global varibale I suppose it would take a lot of work to try to do so.
Do you see, it's something they did years ago and are currently stuck with. Imagine if they had given C/AL a goto command and used it in standard functionality. Whooooooooooooooo!
Of course C/AL is easier to develop with, but that does not mean they cannot try to enforce good practice. A C++ compiler will compile a C program, it isn't difficult to encapsulate things whist retaining backwards compatibility. For example, it wouldn't take them a lot of effort to give you function overloading, or real object references, etc. The ability of a form to say to another form "Hello, I created you, this is me, this is who I am, here is my reference, call my functions to communicate with me" could ease a lot of pain in cases when end clients ask for complicated things to be done. But rather than actually investing in the client and the compiler, they fanny around with the application C/AL which must cost 20 times as many resources to do so, a lot of which is, well....... poor, 2000 line functions in an object with 130 members being a perfect example.
Stop thinking I'm asking for C#, I'm not. I'm asking for responible coding practices.
Maybe we should call it hackware instead of software.
Hilarious.
The ability to change standard functionality, direct nucleus code, is I agree, shocking practice and design. The fact that the designers and programmers of the standard functionality of the application then take advantage of this problem and then write functions 2000 lines long is, well, unforgivable to be quite honest.
The "big boys" were trying to get functions/subroutines/procedures written in procedural type languages down to a maximum of 75 lines over 30 years ago, because they knew very well about concepts such as coupling, cohesion, and even simple software metrics such as LOC and its implications back then.
Many Navision developers seem to have little clue that their is a field of study called Software Engineering and that many people have spent massive amount of time and research effort into defining it. They did not start this process for nothing, although the original idea of the "silver bullet" was a bit far fetched.
Has anyone ever read or even been interested in this type of thing?
http://irb.cs.tu-berlin.de/~zuse/pub/zuse91-cont.html
BTW, the author is the son of a computing legend.
I remember working and debugging code, and it was painful. You couldn't set breakpoints. Having functions called and tracing them would have drove me insane.
I'm sure most C/AL developers felt the same.
Independent Consultant/Developer
blog: https://dynamicsuser.net/nav/b/ara3n
If they would have provided a good IDE (for instance they could have gone to Borland to buy their Turbo Pascal technology) they could have refactored the code in CU80. That would not only have given all the Navision Developers an advantage but also Navision/MS itself.
What we see now is a stinking mess that even they do not seem to want to risk to change.
Hi there,
Are you sure the Object Designer in NAV is not an IDE? To me I always think of NAV as an IDE for C/AL. Correct me if I'm wrong.
Scott
Hi MTC,
I have a MS in SW Engineering and I am an in-house NAV developer in the company. Yes I was thoroughly trained in this discipline. I do agree some of the points you made about NAV (lack of inline documentation and long-winded spagetti code, etc.) but I also want to add some comments on how I see the current practice in NAV.
Developing in NAV is development in maintenance mode, not new development, so you cannot drastically change the existing code base or you risk introducing new bugs. As a good SW engineering practice, I would insert __GB__ between standard and custom varables/functions for readibility (GB short for my company name Gumboots). In-line documentation is beneficial for big development team environment because people other than yourself may have to touch your code one day. However, I believe many NAV developers work alone on a single customization project. Documenting the code may be an after thought.
I have had enough unpleasant experience with one MBS partner because their developers never documented their code or left a change history in Documentation(). Then because of their funny choice of variable names and lack of naming convention, their code was very difficult for me to follow (yes English was not their first language but they were told in advance to follow a coding convention), I ended up having to re-write most of the code. I was told by their project manager not to touch their code. If I ever did, they wouldn't be responsible for maintaining the code for us. He said, "you should just tell us what you want to achieve rather than care how the code is written."
When we first started to roll out NAV more than two years ago, I had spent weeks documenting our functional requirements for one SCM workflow. However in the NAV world these documents may be an overkill to them; I soon discovered no one at the MBS partner could NOT understand my UML class or use case diagrams because C/SIDE is not object-oriented!
Lesson to learn: You have to know what breed of programmers you're working with, how they work (alone or in a team) and what type of development project you're doing (maintenance or new development). If you want to talk NAV, you really should be expressing your requirements in NAV objects (tables, forms, reports, dataports, codeunits), not UML.
You can talk to them about SW engineering discipline and go on and on about the need to document requirements using formal specification languages like UML, in-line comments, but I don't think this would be taken too seriously by some NAV developers (may be perceived more differently w/ C# or Java programmers because of the UML unification).
Speaking of global vs. local, while sometimes it doesn't matter whether you make a Record variable local or global, it is a good SW engineering practice to make variables local whenever possible in order to avoid any side-effects caused by another function within the same codeunit calling the same variable (you risk getting the filters on this variable reset). Also, making variable local mean you never leave any "garbage" behind once the function goes out of scope. This is just good SW engineering practice.
Scott