CodeSOD: The Telltale Snippet
True! nervous, very, very dreadfully nervous I had been and am; but why will you say that I am mad? The disease had sharpened my senses, not destroyed, not dulled them. Above all was the sense of hearing acute. I heard all things in the heaven and in the earth. I heard many things in hell. How then am I mad? Hearken! and observe how healthily, how calmly I can tell you the whole story. - "The Telltale Heart" by Edgar Allen Poe
Today's submitter credits themselves as Too Afraid To Say (TATS) who they are. Why? Because like a steady "thump thump" from beneath the floorboards, they are haunted by their crimes. The haunting continues to this very day.
It is impossible to say how the idea entered TATS's brain, but as a fresh-faced junior developer, they set out to write a flexible web-control in JavaScript. What they wanted was to dynamically add items to the control. Each item was a set of fields- an ID, a tool tip, a description, etc.
Think about how you might pass a list of objects to a method.
ObjectLookupField.prototype._AddItems = function _AddItems(objItems) { if (objItems && objItems.length > 0) { var objItemIDs = []; var objTooltips = []; var objImages = []; var objTypes = []; var objDeleted = []; var objDescriptions = []; var objParentTreeCodes = []; var objHasChilderen = []; var objPath = []; var objMarked = []; var objLocked = []; var blnSkip; for (var intI = 0; intI < objItems.length; intI++) { objItemIDs.push(objItems[intI].ID); objImages.push((objItems[intI].TypeIconURL ? objItems[intI].TypeIconURL : objItems[intI].IconURL)); objTooltips.push(objItems[intI].Tooltip ? objItems[intI].Tooltip : ''); objTypes.push(objItems[intI].TypeID); objDescriptions.push(objItems[intI].Description); objParentTreeCodes.push(objItems[intI].ParentTreeCode); objMarked.push(objItems[intI].Marked ? 'Marked' : ''); objLocked.push(objItems[intI].Locked); // SNIP, not really related } //TATS also implemented `addItems` which requires all these arrays window[this._strControlID].addItems([objItemIDs, objImages, objPath, objTooltips, objLocked, objMarked, objParentTreeCodes, objHasChilderen]); } }
TATS used the infamous "Arrject" pattern. Instead of having a list of objects, where each object has all of the fields it needs, the Arrject pattern has one array per field, and then we'll hope that each index holds all the related data for a given item. For example:
arrNames = {"Joebob", "Sallybob", "Suebob"}; arrAddresses = {"123 Street St", "234 Road Rd", "345 Lane Ln"}; arrPhones = {"555-1234", "555-2345", "555-3456"};
The 0th index of every array contains everything you want to know about Joebob.
Most uses of the Arrject pattern end up in code that doesn't use objects at all, but TATS adds their own little twist. They explode an object into a set of arrays, and then pass those arrays to their own method which creates the necessary DOM elements.
TATS smiled, for what did they have to fear? They bade the senior developers welcome: use my code. And they did.
Before long, this little bit of code propagated throughout their entire codebase; copied, pasted, dropped in, loaded as a JS dependency, hosted on a private CDN. It was everywhere. Time passed, and careers changed. TATS got promoted up to senior. Other seniors left and handed their code off to TATS. And that's when the thumping beneath the floorboards became intolerable. That is why they are "Too Afraid to Say". This little ghost, this reminder of their mistakes as a junior dev is always there, waiting beneath their feet, and it keeps. getting. louder.
[Advertisement] Onsite, remote, bare-metal or cloud - create, configure and orchestrate 1,000s of servers, all from the same dashboard while continually monitoring for drift and allowing for instantaneous remediation. Download Otter today!"Villains!" I shrieked, "dissemble no more! I admit the deed!-tear up the planks!-here, here!-it is the beating of his hideous heart!"