I managed to sneak in a day off of work (split over two days), and built a space for all the tools that I used to keep in my double car garage. We’ve been in the new downtown house now for a year, and had most of the old house cleared out except for the garage. You can accumulate a lot of stuff in 20 years of home ownership, and moving from a house with a double car garage to a no-garage house, was quite a challenge. After many panic-demic induced delays, we eventually finished the renos on the old house, and sold it. I’m really enjoying the new neighbourhood, where I can walk to just about everything I need, but there’s a few things that I miss from the old house:
- The garage!
- Parking spaces (6 not including the garage — I won’t miss shovelling that driveway!)
- The pool.
- The hottub.
However, number 1 — the garage, has been the most challenging. We’ve had stuff from the garage all over the house, in the sheds in the back yard, and a whole lot of it on the back deck under a tarp. We replaced our washer and dryer with a stacking unit to maximize the space, and I’ve now built some heavy duty shelves next to it for all the tools and toolboxes:
I’ve drilled three rows of holes, each 2″ apart, so that I can adjust the height of the shelves. I’ve fixed the middle and the top shelf for stability. I also tacked in the shelf on the bottom with a couple screws and should put some sort of fixed back brace, or a bottom piece so that the side supports cannot spread. That will have to be later, since I’m out of wood (I had to scrounge a bit and my top most adjustable shelf is not big enough — so that one is temporary too.)
We may redo the plumbing on the other side of the washer dryer too. We have some long multiple hose runs, one of which leaked at one point, because of a degraded washer. It would be better to put one of those tidy washer/dryer plumbing boxes right in the wall near the washer dryer instead of the current leak ready to happen system. That would allow for eliminating all the too-long hoses, and give us a chance to fully optimize the long laundry closet for storage. That and the opposite storage unit is the closest that we will get to a “garage” in the new house.
In the 2o year accumulation of stuff, I have a whole lot of tools that actually need to go. Some of these were dad’s, and I didn’t have the heart to toss them, but it would be better to find them homes with people that will actively use them. At the bare minimum, some of these excess tools should go to people who actually have storage space to be hoarders, something that we can no longer do. Now that I have things arrayed in an accessible fashion, it’s time for the big sort, and then the purge after the sort.
May 7, 2020
blocked, COBOL, COBOL FD, DATASET, DDNAME, DSNAME, EBCDIC, eye wash station, fixed, JCL, job step, mainframe, organization, variable
I encountered customer COBOL code today with a file declaration of the following form:
000038 SELECT AUSGABE ASSIGN TO UR-S-AUSGABE
000039 ACCESS IS SEQUENTIAL.
000056 FD AUSGABE
000057 RECORDING F
000058 BLOCK 0 RECORDS
000059 LABEL RECORDS OMITTED.
where the program’s JCL used an AUSGABE (German “output”) DDNAME of the following form:
The SELECT looked completely wrong to me, as I thought that SELECT is supposed to have the form:
SELECT cobol-file-variable-name ASSIGN TO ddname
That’s the syntax that my Murach’s Mainframe COBOL uses, and also what I’d seen in big-blue’s documentation.
However, in this customer’s code, the identifier UR-S-AUSGABE is longer than 8 characters, so it sure didn’t look like a DDNAME. I preprocessed the code looking to see if UR-S-AUSGABE was hiding in a copybook (mainframe lingo for an include file), but it wasn’t. How on Earth did this work when it was compiled and run on the original mainframe?
It turns out that [LABEL-]S- or [LABEL]-AS- are ways that really old COBOL code used to specify file organization (something like PL/I’s ENV(ORGANIZATION) clauses for FILEs). This works on the mainframe because a “modern” mainframe COBOL compiler strips off the LABEL- prefix if specified and the organization prefix S- as well, essentially treating those identifier fragments as “comments”.
For anybody reading this who has only programmed in a sane programming language, on sane operating systems, this all probably sounds like verbal diarrhea. What on earth is a file organization and ddname? Do I really have to care about those just to access a file? Well, on the mainframe, yes, you do.
These mysterious dependencies highlight a number of reasons why COBOL code is hard to migrate. It isn’t just a programming language, but it is tied to the mainframe with lots of historic baggage in ways that are very difficult to extricate. Even just to understand how to open a file in mainframe COBOL you have a whole pile of obstacles along the learning curve:
- You don’t just run the program in a shell, passing in arguments, but you have to construct a JCL job step to do so. This specifies parameters, environment variables, file handles, and other junk.
- You have to know what a DDNAME is. This is like a HANDLE in the JCL code that refers to a file. The file has a filename (DSNAME), but you don’t typically use that. Instead the JCL’s job step declares an arbitrary DDNAME to refer to that handle, and the program that is run in that job step has to always refer to the file using that abstract handle.
- The file has all sorts of esoteric attributes that you have to know about to access it properly (fixed, variable, blocked, record length, block size, …). The program that accesses the file typically has to make sure that these attributes are all encoded with the equivalent language specific syntax.
- Files are not typically just byte streams on the mainframe but can have internal structure that can be as complicated as a simple database (keyed records, with special modes to access them to initialize vs access/modify.)
- To make life extra “fun”, files are found in a variety of EBCDIC code pages. In some cases these can’t be converted to single byte iso-8859-X code pages, so you have to use utf-8, and can get into trouble if you want to do round trip conversions.
- Because of the internal structure of a mainframe file, you may not be able to transfer it to a sane operating system unless special steps are taken. For example, a variable format file with binary data would typically have to be converted to a fixed format representation so that it’s possible to seek from record to record.
- Within the (COBOL) code you have three sets of attributes that you have to specify to “declare” a file, before you can even attempt to open it: the DDNAME to COBOL-file-name mapping (SELECT), the FD clause (file properties), and finally record declarations (global variables that mirror the file data record structure that you have to use to read and write the file.)
You can’t just learn to program COBOL, like you would any sane programming language, but also have to learn all the mainframe concepts that the COBOL code is dependent on. Make sure you are close enough to your eyewash station before you start!