Answered preprocessor and other

Hi everyone,

I continue my understanding of progress and I'm facing a big wall.
This is it:

1. What is exactly a preprocessor name for progress ?
2. In wich case can I used a &SCOPE-DEFINE variable? Why? Advantage & drawback
3. In wich case can I used a &GLOBAL-DEFINE variable? Why? Advantage & drawback
4. In wich case can I used preprocessor test element like &IF &THEN,.... ? Why? Advantage & drawback


Thank you all in advance ;)
 

TomBascom

Curmudgeon
I strongly suggest that you not use the pre-processor.

Pre-processor directives are almost always a sign that the programmer is committing a grave sin and should probably consider a career change.

It’s proper use is within framework code or in environments that are supporting multiple Progress releases and platforms.
 
Last edited:

Rob Fitzpatrick

ProgressTalk.com Sponsor
Preprocessors (names, arguments) are used for conditional compilation of code. They let you write a single source file that may be modified at compile-time, resulting in a program that is functionally different based on some condition in the code. That condition might be OpenEdge version, OS platform, client UI type (GUI vs. TTY), etc.

As Tom indicated, there are places where preprocessors may be useful, letting you do things that are difficult to do in another way, but they are limited. There are also things that preprocessors let you do that can and should be done other ways. You will see some in the documentation. Here is one example:

Code:
/* r-arg.p */
run r-arg2.p "customer" "name"

/* r-arg2.p */
for each {1}:
  display {2}.
end.

You might think "that's easy, now I don't have to learn how to write dynamic queries". Don't write code like this. Ever.

Just because the language lets you do something, it doesn't mean you should.

I'm curious about the reason behind the questions. Do you have a particular problem you are trying to solve and you think using preprocessors are the tool you should use? Or are you just researching ABL language features out of general interest?
 

RealHeavyDude

Well-Known Member
As always, the general usage of pre-processor directives without a valid use-case, is a bad idea. They are resolved at compile time.

But, since the ABL is (still) lacking constants ( immutable variables ) and before the rise of the force ( classes ) in the ABL, I used them to provide constant values so that I don't needed to change them everywhere in the code but just once - where they are defined.
I know that is not sexy but I hate to hard code values and that was one of the options.

But, since now we are able to have public properties in classes with private setters I use those now.
 
Ok thank you :)

I was curious because all the standard programms of my ERP are write with them.

And so I was thinking of an a case that it may help me.

We have our solution in 3 differents places. And we are trying to standardize many of our specifique application.
But It's possible that we need to make a specif like in this example:
exemple.PNG

And maybe the preprocessor is a better solution than a smart object, but I can have a wrong idea.

What's your opinion ?
 

Cringer

ProgressTalk.com Moderator
Staff member
Your diagram does very little to help things. Just because your ERP is written with Preprocessors does not make it a good idea to continue the trend. Preprocessors are evaluated at compile time. The only thing they are useful for is when you're writing code to run across various Progress versions. Say, you wanted to include some .Net code, but your app is run on v9 as well (poor you!), then you could use a preprocessor to decide what version this is and to just display some sort of error to the user, excluding the stuff that won't compile in v9.
Using preprocessors to decide what to do based on some sort of business logic is a really bad idea. Not least of all because they are not transparent to a developer.
With all due respect, it would be a very good idea to become proficient with the Progress language before starting to think about how you could change the architecture of your application. Making architecture decisions with minimal understanding of what the language can do will lead to bad choices and horrible solutions that help nobody.
 
Your diagram does very little to help things. Just because your ERP is written with Preprocessors does not make it a good idea to continue the trend. Preprocessors are evaluated at compile time. The only thing they are useful for is when you're writing code to run across various Progress versions. Say, you wanted to include some .Net code, but your app is run on v9 as well (poor you!), then you could use a preprocessor to decide what version this is and to just display some sort of error to the user, excluding the stuff that won't compile in v9.
Using preprocessors to decide what to do based on some sort of business logic is a really bad idea. Not least of all because they are not transparent to a developer.
With all due respect, it would be a very good idea to become proficient with the Progress language before starting to think about how you could change the architecture of your application. Making architecture decisions with minimal understanding of what the language can do will lead to bad choices and horrible solutions that help nobody.

Thank you Cringer for your help and advice.

So, if i understand it right, the used of preprocessor is not a good idea in 99.99% case and they are many more tools to do what i wanna do ?

Maybe to say it in a more clearly way:

I have 3 differents db that work separetly, each one is attribute to a country, like USA, CHINA and FRANCE.
My main issue is - to put it simply - I want to write a common application for each of our country plant but for one of them I need to add a specification (like a supplement browse) for the plant in FRANCE that I don't want to see in the plant of USA and China.

is there a way ?
 

Cringer

ProgressTalk.com Moderator
Staff member
This is definitely not a use-case for preprocessors. It sounds like all you need to do is to conditionally display the extra data based on some setting in the database. If database structure, Progress version and code are all the same on each site your life will be a lot easier.
 

TomBascom

Curmudgeon
Normally you would build such functionality using an ordinary IF statement.
Code:
if country = "USA" then
  do:
  end.
 else if country = "China" then
  do:
  end.
 else if country = "France" then
  do:
  end.

Of course hard coded constants are a sign that you have an opportunity to improve your code so, if you want to be more flexible, you might instead do it like this:

Code:
run value( substitute( "cust_&1.p", country )).

To say nothing of all the possibilities with dynamic widgets.

There are, of course, numerous other approaches. The point is that by doing it in code the decisions are made at run time, quite possibly based on data values stored in configuration tables, which results in much more flexible deployments.

Whereas using a pre-processor the decisions are made at compile time and now you need to manage multiple sets of r-code. (Among many other bad things that means that when a user reports an error on line XYZ you will also need to find the debug listing that goes with the proper version of the r-code because pre-processors change the line numbers and no two releases will be the same...)
 
Normally you would build such functionality using an ordinary IF statement.
Code:
if country = "USA" then
  do:
  end.
else if country = "China" then
  do:
  end.
else if country = "France" then
  do:
  end.

Of course hard coded constants are a sign that you have an opportunity to improve your code so, if you want to be more flexible, you might instead do it like this:

Code:
run value( substitute( "cust_&1.p", country )).

To say nothing of all the possibilities with dynamic widgets.

There are, of course, numerous other approaches. The point is that by doing it in code the decisions are made at run time, quite possibly based on data values stored in configuration tables, which results in much more flexible deployments.

Whereas using a pre-processor the decisions are made at compile time and now you need to manage multiple sets of r-code. (Among many other bad things that means that when a user reports an error on line XYZ you will also need to find the debug listing that goes with the proper version of the r-code because pre-processors change the line numbers and no two releases will be the same...)


Thank you for your example, in my system I can set a environment variable that can be common to each of my plant and in fact can test at runtime to add my specif application.


And yes @ Cringer I know. I've the same point of view but mine is not always my team point of view.

Like my recent threads I tried to unified all the code for each of the plant in the optic of maintining one and unique version for each app.

I can say that it's not an easy task, I start progress the last february and you help me a lot to understand difficult case, so thank you all ;)
 
Top