Recent

Author Topic: Global variable alternative  (Read 4667 times)

k1attila1

  • Full Member
  • ***
  • Posts: 108
Global variable alternative
« on: March 22, 2020, 10:55:51 am »
Hi

In my programs i usually use Global variables (not too much). (for example : i read something from registry and the result will be used in in many part of the application (printer settings) etc.)
How can i replace it ?
Is there always alternative for Global Variables ?

Thank you Attila

Otto

  • Full Member
  • ***
  • Posts: 226
Re: Global variable alternative
« Reply #1 on: March 22, 2020, 11:13:54 am »
Hi
Of course, there are many alternative, but it all depends on the specific case.

In your specific case I would advise you to dedicate a Unit to this purpose.

Otto.
« Last Edit: March 22, 2020, 11:16:26 am by Otto »
Kind regards.

JD

  • Hero Member
  • *****
  • Posts: 1910
Re: Global variable alternative
« Reply #2 on: March 22, 2020, 11:32:39 am »
Stay away from global variables, use the Singleton design pattern instead. It is better for OOP.

https://schellingerhout.github.io/design%20patterns/design-patterns-creational-delphi/

https://sourcemaking.com/design_patterns/singleton/delphi

JD
Linux Mint - Lazarus 4.0/FPC 3.2.2,
Windows - Lazarus 4.0/FPC 3.2.2

mORMot 2, PostgreSQL & MariaDB.

k1attila1

  • Full Member
  • ***
  • Posts: 108
Re: Global variable alternative
« Reply #3 on: March 22, 2020, 11:41:21 am »
Thanks both of you

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Global variable alternative
« Reply #4 on: March 22, 2020, 11:48:29 am »
The links provided by JD make interesting reading.
It is however worth pointing out that blanket application of OOP is not recommended by all software designers. Indeed there is a well-represented  group of experienced programmers who refuse to use it at all. Although understandably they do not frequent this forum.

You can never avoid global variables entirely.
If you study the Lazarus sources you will see that they make considerable, but judicious, use of global variables, and almost never use interfaces, preferring abstract base classes.



dbannon

  • Hero Member
  • *****
  • Posts: 3685
    • tomboy-ng, a rewrite of the classic Tomboy
Re: Global variable alternative
« Reply #5 on: March 22, 2020, 12:36:38 pm »
Global variables got a bad name back in the very early days of programming because they quickly became unmanageable as an application grew.  The real problem was when various parts of the application was allowed to change the variable, you very quickly found yourself wondering "who did that?".

The use of globals does make sense for some use cases, particular settings. I have a 'settings' unit that reads the settings in from a file, and makes those values available to other units as needed. In most cases, thats read only.

But the user can sometimes change settings and at times like that, the unit where the changes are made must have a way of telling the settings unit about that change. In most cases, when that happens, the settings file needs to be updated as well as the relevant global var.  Its a classic case  for properties.  The write to property can do some sanity checking and trigger actions like saving.

So, nothing evil about global vars, just limit their use and regard them as read only (and maybe enforce that with properties) where ever possible.  You can easily search through all your units to find just which units are writing to a global, as a linux user, its the grep command and used often !

grep -ni "blah :=" *.pas

Davo

In
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

440bx

  • Hero Member
  • *****
  • Posts: 6093
Re: Global variable alternative
« Reply #6 on: March 22, 2020, 12:46:14 pm »
It is however worth pointing out that blanket application of OOP is not recommended by all software designers.
Fortunately, there are some of those.

Indeed there is a well-represented  group of experienced programmers who refuse to use it at all. Although understandably they do not frequent this forum.
I guess I am one of the exceptions.  I frequent the forum and, I enjoy doing so. :)

You can never avoid global variables entirely.
Yes, you can.  Actually, the presence of global variables is a good indication of a design flaw (they are ok in "throw away" code.)  If the application is well designed, the count of global variables is _zero_.

If you study the Lazarus sources you will see that they make considerable, but judicious, use of global variables, and almost never use interfaces, preferring abstract base classes.
OOP makes it more complicated than it should be to have a program without global variables.  I don't use OOP but, I believe it's possible to design OOP applications that do not use any global variables (it's probably not easy.)
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Global variable alternative
« Reply #7 on: March 22, 2020, 01:06:15 pm »
You can never avoid global variables entirely.
Yes, you can.  Actually, the presence of global variables is a good indication of a design flaw (they are ok in "throw away" code.)  If the application is well designed, the count of global variables is _zero_.
I should have written that in a GUI LCL program you cannot avoid using global variables.
Do you consider the Lazarus IDE a "throw-away" program?

wp

  • Hero Member
  • *****
  • Posts: 13358
Re: Global variable alternative
« Reply #8 on: March 22, 2020, 01:26:35 pm »
In my programs i usually use Global variables (not too much). (for example : i read something from registry and the result will be used in in many part of the application (printer settings) etc.)
How can i replace it ?
Is there always alternative for Global Variables ?
There's nothing bad about global variables when these are really used every in the program.

However, what I often see here in the forum, mostly in the code of beginners, is that variables are declared globally although they belong to a form or another class or should even be declared locally. An (extreme) example is this:
Code: Pascal  [Select][+][-]
  1. type
  2.   TForm1 = class(TForm)
  3.     Button1: TButton;
  4.     Edit1: TEdit;
  5.     Edit2: TEdit;
  6.     procedure Button1Click(Sender: TObject);
  7.   private
  8.  
  9.   public
  10.  
  11.   end;
  12.  
  13. var
  14.   a, b, c: Integer;
  15.  
  16. procedure TForm1.Button1Click(Sender: TObject);
  17. begin
  18.   a := StrToInt(Edit1.Text);
  19.   b := StrToInt(Edit2.Text);
  20.   c := a + b;
  21.   ShowMessage(IntToStr(c));
  22. end;

In this particular example a, b, and c are only used in the click procedure of the button, nowhere else. Therefore, they should be declared as local variables of this procedure:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   a, b, c: Integer;
  4. begin
  5.   a := StrToInt(Edit1.Text);
  6.   b := StrToInt(Edit2.Text);
  7.   c := a + b;
  8.   ShowMessage(IntToStr(c));
  9. end;


MarkMLl

  • Hero Member
  • *****
  • Posts: 8533
Re: Global variable alternative
« Reply #9 on: March 22, 2020, 01:30:19 pm »
I should have written that in a GUI LCL program you cannot avoid using global variables.
Do you consider the Lazarus IDE a "throw-away" program?

It would- in my opinion- be highly desirable if things like form variables were immutable once they'd been set during initialisation, i.e. were only exposed as a function result or a property of the unit in which they're defined.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

MarkMLl

  • Hero Member
  • *****
  • Posts: 8533
Re: Global variable alternative
« Reply #10 on: March 22, 2020, 01:39:43 pm »
Global variables got a bad name back in the very early days of programming because they quickly became unmanageable as an application grew.  The real problem was when various parts of the application was allowed to change the variable, you very quickly found yourself wondering "who did that?".

More seriously, they got a bad name when  FORTRAN was still a major player on account of COMMON blocks:


Every subroutine or user-defined function that uses data stored in the COMMON block, blank or named, must have a similar statement to those above. The variable names do not need to match between program units but it is vital that their types and the order in which they appear in the list are identical.


There's definitely a valid use for globals, provided that the compiler (unlike 1960s FORTRAN) type-checks them properly. However where a language provides an efficient alternative, using that is almost certainly preferable.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

440bx

  • Hero Member
  • *****
  • Posts: 6093
Re: Global variable alternative
« Reply #11 on: March 22, 2020, 01:42:19 pm »
I should have written that in a GUI LCL program you cannot avoid using global variables.
Do you consider the Lazarus IDE a "throw-away" program?
The presence of global variables doesn't mean the application is a throw away program but, it does mean, it could have been designed better.  A common problem, that the majority of programmers are familiar with is: the more designers there are involved in the creation of a program, the more likely the design could have been better. 

I believe it should be possible to design a GUI LCL program without any global variables.  That said, considering that my experience with the LCL is an absolute zero, I could easily be mistaken but, at least in theory, it should be possible (clarification: that does not include _removing_ already existing variables in the LCL, it means, not adding any new ones in the process of writing a new app.)

FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Otto

  • Full Member
  • ***
  • Posts: 226
Re: Global variable alternative
« Reply #12 on: March 22, 2020, 01:43:37 pm »
@440bx

OOP makes it more complicated than it should be to have a program without global variables.  I don't use OOP but, I believe it's possible to design OOP applications that do not use any global variables (it's probably not easy.)

Hi
You're right. In non-FPC languages, such as e.g. C#, the use of global variables is not an option to consider. There are static classes and other features to work around this problem, but often the code becomes very complex. That's why I prefer the version of the OOP implementation commonly used in FPC over that of the C. Also in FPC, if necessary, you can do without the OOP.
Otto.
Kind regards.

jamie

  • Hero Member
  • *****
  • Posts: 7543
Re: Global variable alternative
« Reply #13 on: March 22, 2020, 02:29:18 pm »
That problem is very simple to solve.

When you start a project, create a UNIT that all other units will use. For example

Unit ProjectName_COM;


and include all the global data within that unit and also include the unit itself within the USES list of all other units that requires it.

 No code duplications etc. The problem is solved.



The only true wisdom is knowing you know nothing

440bx

  • Hero Member
  • *****
  • Posts: 6093
Re: Global variable alternative
« Reply #14 on: March 22, 2020, 02:37:47 pm »
... include all the global data within that unit and also include the unit itself within the USES list of all other units that requires it.

No code duplications etc. The problem is solved.
The problem isn't really solved. Putting all the global variables in one container doesn't get rid of them. It's definitely better than having them all over the program but, the problems they create still exist.

FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018