Rexx Programming "Rules of Thumb" by Howard Fosdick - 2005, 2006 Introduction-- Rexx is one of the most flexible, capable programming languages around. Its range of options and power means that some stylistic "rules of thumb" can be helpful. This list offers some. The list includes "common errors" as well. Remember them to reduce your debugging time and write error-free code. This material is extracted and abbreviated from the book Rexx Programmer's Reference. The book provides fuller explanations and examples of the rules briefly listed here. Optimal "rules of thumb" can vary somewhat according to whether you're writing a short script or a large programming system. I note rules of thumb that are specially recommended practices for large systems. They are collected towards the bottom of the list. If you have any "rules of thumb" to contribute to this list, please send them to the webmaster for this site (webmasterA at the domain of rexxinfo.org). I will attribute them to you. Thank you! Rexx Rules of Thumb-- Write Readable Code, Not "Fortune-Cookie" Code Some programmers like to write clever, "fortune-cookie" code. Their code doesn't live long because it can not be maintained. Strive to write the most readable, maintainable code, not the shortest or most clever code. This first rule is the basis for many that follow. Capitalize on Capitalization Take advantage of Rexx's case-insensitive nature to make code more readable. Use Good Variable Names Since you can use long variable names, do so for readability. Include embedded underscores in names too -- Good -> Social_Security_Number Poor -> sno Use Spacing and Indentation Take advantage of Rexx's free-format nature. Indent according to the nesting level of IF and DO statements. Line up ENDs as appropriate. Code whose horizontal alignment matches its logic is much easier to read and maintain. Limit Expression Nesting You can nest expressions to any depth, but readability is better served by breaking up nested expressions into separate lines of code. Ever had to maintain someone else's highly-nested expressions? It's very difficult. Comment Code Rexx's free-form comments allow you to comment your code wherever and however you like. Well-commented code is way easier to maintain than code without explanation. Maintain Code Comments When you maintain code, you must update the code comments also. Otherwise they will become misleading rather than an aid. Handle Errors Good code is robust and fail-safe. Handle all errors from— · Command results · Interpreter-raised error conditions · Return codes from interfaces · I/O results Use Rexx's Built-in Error and Exception Handling to Manage Errors While there are some cases where you will not want out-of-line error handling, you should normally employ Rexx's built-in exception handlers. Check All Return Codes Good programs check all return codes to ensure their robustness and viability. Explicitly Initialize Subscripts Explicitly initialize a subscript at the top of the DO loop at which it is used. Do Not Alter Subscripts Inside Loops Do not explicitly alter a subscript variable while within a loop. Let the DO instruction increment it for you naturally. Use Top-Driven Loops Only Use only top-driven DO loops. Bottom-driven loops do not conform to the rules of structured programming. Don't Exit From Inside a Loop Do not early force-exit from within a DO loop. Structured programming only allows for normal exit at the loop's top-driven condition check. Use a Loop Subscript Only for a Loop If you use a variable like I for subscripting a DO loop, do not also use it to index a table from within that loop! If You Nest Loops, Use a Different Subscript for Each If you don't follow this principle, your logic won't work properly. When nesting DO loops, you've got to use a different subscript for each DO. Build OS Commands in Simple Steps Build strings that represent operating system commands in several simple steps, not in a single huge, complicated statement. Build OS Commands in a Variable Build strings that represent operating system commands within a variable. You can then display the variable to ensure the command string is properly created. Avoid Unnecessary Quotation Marks in Building OS Commands One sometimes sees double-quoting when building operating system commands for mainframe environments. This is not necessary and hurts the readability of the code. Use as few quotes as possible when concatenating command strings. Use Rexx-Aware Editors Using a Rexx-aware editor can reduce your error rate. Example products include: * THE (The Hessling Editor) for Windows, Linux, Unix, etc. * The REXX Text Editor (RexxEd), distributed with Reginald for Windows * The Interactive System Productivity Facility (ISPF) on mainframes * XEDIT on mainframes Publish Site Style Standards This renders code at a site similar regardless of the author. Consider what your enforcement mechanism should be. Use Automated Tools to Ensure Standards Compliance Many sites buy or develop tools to ensure standards compliance and the similarity of code across authors. Templates that programmers fill out for documentation purposes are one good example. Consider Code Reviews Code reviews are another technique to ensure common code style and conformance to site standards. Don't Forget to End a Comment Every comment must be ended by */. Otherwise your program becomes one long comment! Don't Forget to End a Literal String or Parenthetical Expression Same as ending a comment… you must do it! Don't Forget RETURN or EXIT Remember that functions must return a string to the caller; subroutines may optionally do so. Be sure to code RETURNs and EXITs where required. Don't Overlook Automatic Upper-case Conversion Remember that instructions like PULL and ARG auto-convert to upper-case. If you do not want auto-conversion, use PARSE PULL and PARSE ARG. This can be especially important if your program reads in file names. File names are case-sensitive in Linux and Unix, but not in Windows. Left Parentheses Must Immediately Follow Functions Don't forget to immediately follow a function by a left parenthesis. No intervening space is allowed. Incorrect -> rc = function_name (argument1) Correct -> rc = function_name(argument1) CALLs Do Not Use Parentheses Remember that CALL statements do not use parentheses to enclose arguments. Incorrect -> call subroutine(argument1, argument2) Correct -> call subroutine argument1, argument2 Don't Forget that Functions Return Strings Don't forget that a function returns a string. You must provide a place for the string to go. Incorrect -> function_name(argument1) Correct -> feedback = function_name(argument1) Correct -> call function_name argument1 Watch Statement Continuations Remember that the comma is Rexx's line continuation character. Surround comma's used for statement continuation with blanks for readability. Line them up if multiple ones occur across several lines. Use Strict Comparisons When Required If you want to compare a string including its preceding or following blanks, be sure to use Rexx's strict comparison operators. Don't Strict-Compare Numbers Strict comparisons are for strings, not for numeric values. Don't Use DO UNTIL Structured programming doesn't permit bottom-driven loops. Any such loop can be structured properly by using the DO-WHILE instead. Don't Use SIGNAL as a GOTO Structured programming does not allow GO TO's. Use structured control constructs instead (DO, IF, etc). Set a control flag if necessary to convert your GO TO's to IF's and DO's. How to Return More than One Value from a Function Rexx functions return a single value only. If you want to return more than one value you can: * Concatenate the values into one returnable string, then use PARSE in the caller to get the individual values * Write values to a file, which you use as a global passing mechanism How to Iterate Over all Tails in a Stem Variable This is not part of ANSI-standard classic Rexx. But many Rexx interpreters have this built-in as an extra (for example, Open Object Rexx, roo!, Reginald, and BRexx). Or you can use any of several add-on packages that support this (for example, REXXUTIL). Leverage Rexx's Interactive Trace Facility The big advantage to interpreters is interactive debugging. Leverage Rexx's built-in debugging facilities to greatly reduce your debugging time. Maintain a Site-wide Function or Object Library Code re-use can only happen if you put the proper mechanisms in place to facilitate and encourage it. Consistency is the Mother of All Virtues -- especially for large programs! Whatever coding style you pick, apply it consistently. Consistency may be the "hob-gobblin of small minds," but in coding it is a key virtue. If you've ever had to read and maintain a large set of programs written by someone else, you'll know what I mean. Write Structured Code -- especially for large programs! Structured programming has been established for over twenty years ago as a superior programming methodology, especially for large programs. Use it if you wish to write maintainable code. Write Modular Code -- especially for large programs! Modular principles complement structured programming principles. Both have long been proven superior coding techniques. If you don't believe me, you might read Yourdon and Constantine. Declare All Variables -- especially for large programs! Not declaring variables is easy and convenient for small scripts. But declare all variables for larger systems! Otherwise you'll likely experience errors based on uninitialized variables. Use the NOVALUE built-in exception handler to trap any variable that has not been properly assigned a value. Don't Use Global Variables -- especially for large programs! Programmers often use global variables because they're easier than passing arguments. But for large programs, the most common maintenance errors are due to global variables. I recommend you not use global variables, especially on larger projects. Sometimes a configuration or ini file works well for storing global variables, or even a single routine that is effectively a just memory definition or "control block" definition. |