Re: avoiding huge globals files
Posted in 1996
In article <595i9t$hjs@gulfa.kuwait.net>, Rudy Fernandes <rferdy@kuwait.net> writes >Great! I was looking for a discussion on globals with somebody who actually >advocates them (rather than use them by accident), and it looks like I've >got one. > I also agree with use of globals but only in a very limited sense. E.g. one on my library functions is cursor handling open_cursor(select statement,...) returning cursor_id close_cursor(cursor_id) etc (there are quite a few functions...). The way to implement this is have an array which tracks info about each cursor:- Arrays Cursors[20] of record status char(1) "A"vailable /"U"sed select_statement char(1000) ..... end record The main cursor handling functions (used by programs) each contain case statements calling functions to actual do the work since cursor names are not dynamic:- function close_cursor(cursor_id) = case when cursor_id = 01 call close_cursor_01() when cursor_id = 02 call close_cursor_02() otherwise <call error handler> end case end function Now each cursor has a unique name (MY_CUR_NN) where NN is the cursor id and quite a few functions associated with it so exists in a separate module :- Module cursor01 function close_cursor_01 CLOSE MY_CUR_01 end function This means you can do nice things like use sed to substitute 01 for the next number if you need to extend the library to handle more cursors. Also without separate modules you would have thousand of lines of code in one module. However the array of cursors needed to be held globally to all modules to allow the open function to find an available cursor. Hence the array is defined in a globals file. This globals file is ONLY included in these library modules. Hence the global array only be accessed by calls to these functions!!!!!!!! This is a useful technique that means state information can be held within library functions without allowing access outside the given SUBSET of library functions. It effect you create a "object" within defined "method" functions and internal state WHERE ALL ACCESSES HAVE TO BE VIA MEMBER FUNCTIONS. Who said 4GL is not object orientated :->. This idea can also be applied at the module level to allow state info to be held within a particular module by using module level variables. You can periodically grep throught the code for the name of the globals module to make sure it is only accessed within the required modules. Globals are useful but you have to use them in a controlled manner. Do not use them to pass values into library functions but to hold state information within the library functions between function calls where use of one module and module level variables is not appropriate. This means memory is not continually allocated/deallocated. I also agree with always creating library functions where possible but this should be done at design time i.e. there should be no need to take a function out of a program and create a library function. If I need to do this then I generally rewrite it to make it more generic rather then just paste it into a new library module. >And you have obviosly never encountered the many memory 'leaks' available >at no extra cost in 4GL. ( Errors like -4518 ;-) Yes I have but by making good use of library functions I can narrow down where it occurs by adding debugging code to commonly called library functions. Informix provided a tss_hog function to tell you when a memory leak had occured. -- David Williams