IBM Releases Constant Standalone Fields to RPG

Bad Joke of the Month
I just overheard that Earl is real mixed up. (You may have to read it again to get it.)
IBM Releases Constant Standalone Fields to RPG
This spring, IBM added support for “Constant Standalone
Fields” to RPG. To avoid confusion with other types of constants (figurative
constants, named constants, enumerated constants) that exist in the language, I
find myself referring to them as “variables that can’t be changed” or
“unchangeable fields.” In this post, I’ll give you the low-down on this new feature.
Variables That You Can Only Change in the INZ Keyword
What distinguishes these from the other types of constants is that they’re really just variables that the compiler tries to stop you from changing. You can set their values with the INZ (initialize) keyword, but after that, you can’t change them again. (Technically, there are probably ways to “trick” the compiler into changing them, but… let’s not do that!)
For example, I can do this:s
dcl-s UserId char(10) inz(*user) const;
In this example, UserId has the CONST keyword, which means that you can’t change it, except with the INZ keyword. In this case I have INZ(*USER) which means when the program or subprocedure that contains this variable definition is started, it retrieves the current user profile and puts it into the UserId variable.
If I tried to change UserId, the program wouldn’t compile.
UserId = *blanks;
aaaaaa
*RNF5346 30 a 002500 The operation modifies the field, but the field cannot be modified.
That’s useful to prevent program code from accidentally changing something that shouldn’t be changed, but whose value isn’t known until program initialization. For example, the current date, the length of a variable, the number of elements in an array, etc.
Another interesting usage is for data structures. Data structures can be initialized the same as another data structure with INZ(*LIKEDS) or the same as an external file (when using an externally defined data structure.)
For example, consider this physical file definition with default values specified:
…..A*………T.Name++++++RLen++TDpB……Functions++++++++++++++++++
A R TESTFMT
A TERMS 1A TEXT(‘Credit Terms’)
A DFT(‘M’)
A REGION 1A TEXT(‘Sales Region’)
A DFT(‘1’)
A SALREP 4A TEXT(‘Sales Rep (Sales person)’) A DFT(‘NONE’)
Or, if you prefer, it can be the SQL (DDL) equivalent:
create table dftval (
terms char(1) not null default ‘M‘,
region char(1) not null default ‘1‘,
salrep char(4) not null default ‘NONE‘
)
rcdfmt testfmt;
In either case, you can define an RPG data structure with INZ(*EXTDFT) to initialize a data structure to the defaults from the file. For example:
dcl-ds Defaults ext extname(‘DFTVAL’) qualified inz(*extdft) const end-ds;
This can be useful if you want to set a record to the default values, and then perhaps later, override one of the values (or insert user-supplied values.) For example:
dcl-ds Defaults ext extname(‘DFTVAL’) qualified inz(*extdft) const end-ds;
dcl-ds rec ext extname(‘DFTVAL’) qualified inz(*extdft) end-ds;
.
.
rec = Defaults;
rec.Terms = ‘X’;
In this example, I have two copies of the same external data structure, but one of them is not changeable, and has the default values from the file.
At some later point in my program (after the user has changed the values) I can simply use rec = Defaults (as shown above) to reset it back to the default values. I can’t change the values in ‘Defaults’, but I can change the values in rec, so I could override a default (such as setting the terms to X, above.)
Later I could check to see if it contains default values very easily.
if rec = Defaults;
// do something interesting
endif;
“Unchangeable variables” (defined with CONST as in the examples above) can be passed as parameters to subprocedures, programs, etc as long as the parameter in the prototype you are calling is also defined with CONST. If CONST is absent, it will assume that the routine can change the parameter, so the compiler will stop you.
My opinion? There are times when this wlll be useful, mostly to save us from our own mistakes, or to speed up code analysis (since the reader can tell a variable is unchangeable, if he/she is looking for the code that makes a change, they can skip anything with CONST, so it saves them time and effort.)
Most of the time, though, it’s probably not useful since there’s a limited number of things you can assign with the INZ keyword that aren’t known at compile-time. Hopefully over time the INZ keyword will get more capabilities, which in turn will make this new feature more useful.
How Do I Get These Features?
These new features were released alongside the technology refreshes for the operating system and are available via PTF for IBM i 7.4 and 7.5. You can find the PTF numbers here: https://ibm.biz/rpg_cafe