Lazarus

Programming => General => Topic started by: dodgebros on March 26, 2020, 04:53:52 pm

Title: Global / Public constants
Post by: dodgebros on March 26, 2020, 04:53:52 pm
I want to define a constant in a datamodule then be able to access that constant from other units.  Where in the datamodule unit would I declare the constant and how?

Hope this makes sense,
TD :o
Title: Re: Global / Public constants
Post by: lucamar on March 26, 2020, 05:44:03 pm
A data module is just a unit like any other, so to make any type, constant, var, etc. declared in it accessible from the outside just declare them in the interface section.

For example:

Code: Pascal  [Select][+][-]
  1. unit Unit2;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils;
  9.  
  10. type
  11.   TDataModule1 = class(TDataModule)
  12.   private
  13.   public
  14.   end;
  15.  
  16. var
  17.   DataModule1: TDataModule1;
  18.  
  19. const
  20.   sHello = 'Hello from the data module!';
  21.  
  22. implementation
  23.  
  24. {$R *.lfm}
  25.  
  26. end.
Title: Re: Global / Public constants
Post by: dodgebros on March 26, 2020, 11:52:00 pm
Thank you lucamar, that did it.

I also found that to refer to the contstants on another unit, you do not refer to them as datamodulename.constantname, you refer to them simply by the constant's name.

Thanks again for the help!
TD
Title: Re: Global / Public constants
Post by: GypsyPrince on March 27, 2020, 06:14:58 pm
@dodgebros

Something I just recently learned through experiment which might be of a little help to you...

Pascal units don't seem to like circular references.

i.e., If you reference 'Unit2' inside 'Unit1', then you cannot reference 'Unit1' inside 'Unit2'.

When I say "reference", I mean you can't put the name in the 'Uses' section of the module.

A small number of programming languages do allow for circular references between modules. But, as I found the hard way, the Pascal compiler throws a temper tantrum when that is done.

In many of my programs, the routines in my modules "communicate" back and forth to each other.  In order to achieve this, I've had to create a "global" module containing the data fields (variables and constants) and routines (procedures, functions, and event handlers) which 'Unit1' and 'Unit2' both utilize.  Both 'Unit1' and 'Unit2' reference 'UMain' (global unit), but they do not reference each other, and 'UMain' doesn't reference any other modules except the default (Uses Classes, SysUtils;).
Title: Re: Global / Public constants
Post by: lucamar on March 27, 2020, 07:27:22 pm
Pascal units don't seem to like circular references.

i.e., If you reference 'Unit2' inside 'Unit1', then you cannot reference 'Unit1' inside 'Unit2'.

When I say "reference", I mean you can't put the name in the 'Uses' section of the module.

That's not exactly as you say: you can make two units refer to each other; just not in the same section, so if A "uses" B in the interface then B can "use" A in the implementation, or viceversa.

It's true, though, that having to do so usually means there is some design mishap, so it's better to avoid those situations from the start if at all posible.
Title: Re: Global / Public constants
Post by: mercurhyo on March 28, 2020, 03:20:32 am
smh

Circular references are Ok when in the IMPLEMENTATION section of units!

little trick LOL
to make procedures, functions, and so on ... GLOBAL, check the 'public', 'export' and 'external' modifiers... I mean 'export', not 'exports'

Code: Pascal  [Select][+][-]
  1. procedure myprocedure(t: string); public; { make it public til ASM lvl, case sensitive at ASM}
  2. begin
  3. ...
  4. end;
  5.  
here, public is a modifier, telling the procedure is global, not a declarative block command
Title: Re: Global / Public constants
Post by: winni on March 28, 2020, 03:47:44 am
Hi!

Yes - that is allowed and documented since Delph 1.
That was 1995.

Winni
Title: Re: Global / Public constants
Post by: mercurhyo on March 28, 2020, 04:04:28 am
@winni  ;)

Ok it's bad habit to my taste, because it breaks the "STRUCTURED" programin way (just my personal opinion), but

yep, one can make procedures, variables, funcs, 'public', in many units and then reference the whole thing inside an INClude file or inside other units, with 'external' modifiers without dynamic libs names. the linker will do the job and find them.

no need to sink with a 'global module containing the data fields' as mentioned by @Gypsy
Title: Re: Global / Public constants
Post by: GypsyPrince on March 28, 2020, 06:42:14 am
Interfaces can also be used to allow for circular references, as can a couple of other methods.

However, here are some discussions on why all methods, and forcing circular references in general, produces many unintended and unpleasant consequences.

https://stackoverflow.com/questions/2644973/getting-around-circular-references-in-delphi (https://stackoverflow.com/questions/2644973/getting-around-circular-references-in-delphi)
https://stackoverflow.com/questions/2356318/delphi-enterprise-how-can-i-apply-the-visitor-pattern-without-circular-referenc (https://stackoverflow.com/questions/2356318/delphi-enterprise-how-can-i-apply-the-visitor-pattern-without-circular-referenc)
https://stackoverflow.com/questions/2644973/getting-around-circular-references-in-delphi (https://stackoverflow.com/questions/2644973/getting-around-circular-references-in-delphi)
http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-Circular-references-and-code-quality-td3392648.html (http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-Circular-references-and-code-quality-td3392648.html)

For a newbie, utilizing a third unit which causes no issues may provide a better (and safer) way to learn.
Title: Re: Global / Public constants
Post by: mercurhyo on March 28, 2020, 02:13:07 pm
However, here are some discussions on why all methods, and forcing circular references in general, produces many unintended and unpleasant consequences.

this is named "Diamond of Death" in C++ world. So, .... Pascal tried to avoid such crapy jewel. All 'circular references' tend to end with Devil's Diamond of C++ dung
Title: Re: Global / Public constants
Post by: mercurhyo on March 28, 2020, 02:17:22 pm
better keep yer minds structured ;) guys
Title: Re: Global / Public constants
Post by: BeniBela on March 28, 2020, 06:36:16 pm
I have too many circular references in the implementation section and now I get " Error: Internal error 200611031 "  or "Compiler raised exception internally" all the time when I compile my project
Title: Re: Global / Public constants
Post by: lucamar on March 28, 2020, 09:04:09 pm
Frankly speaking, I would try to avoid at all costs any and all circular references; instead I would extract the "common" parts to their own unit(s).

It's, of course, not always posible, but decoupling common parts  to their own units simplifies debuging enormously, not to mention that it makes the design cleaner and easier to maintain, in my experience.

Even just moving message/resource string constants to their own unit and "using" that unit where needed can have a big impact on the "maintainabilty" (if that word exists) of almost any project; figure then the impact of decoupling more complex code.

Just my humble opinion, of course (backed by a few years experience, whatever that's worth :) ).
Title: Re: Global / Public constants
Post by: GypsyPrince on March 29, 2020, 06:56:22 am
@lucamar

Quote
Frankly speaking, I would try to avoid at all costs any and all circular references; instead I would extract the "common" parts to their own unit(s).

There needs to be a "thumbs up" emoji for such occasions as this one!!
TinyPortal © 2005-2018