Feed the-daily-wtf The Daily WTF

Favorite IconThe Daily WTF

Link http://thedailywtf.com/
Feed http://syndication.thedailywtf.com/TheDailyWtf
Updated 2024-11-22 01:16
Best of…: Best Of 2021: Worlds Collide
Best of…: Best of 2021: It's a Gift
Error'd: Some Like It Hotter
Fast approaching the end of the Gregorian calendar, things start to happen all at once, just to get them over with. According toDaniel D. "It's November 21 and Facebook can't decide which tomorrow comes first."
CodeSOD: Git Pull, for the Holidays
We're heading into the holiday season. We had some rather ambitious plans for a special Christmas event, but for a variety of reasons, all the various moving parts couldn't come together.There's always next year, though. Instead of rehashing Christmas carols or doing our own parodies of holiday specials, I figured we should share one of the songs we wrote for that unfinished special event. It's got good advice for those of us heading into the holiday season: don't release anything to prod in the next few days. LyricsGit Pull
CodeSOD: Masking Errors
Dirk's employer bought some software from a vendor, and the vendor promised that it was a cutting edge system, which was pushing the boundaries of technology. Digging through the API documentation, Dirk definitely found some unusual innovations, like the way it tracked log levels:
CodeSOD: Again and Again
"It's a fix for a fix for a fix, apparently," writes Joan.In this case, it's some Ruby code, which… gets a bit repetitive in that it repeats itself and does the same thing over and over again, in a repetitive fashion. Repeats.
CodeSOD: Voicemail to Email to Nothing at All
Mike's co-worker doesn't like to write code that gets tightly coupled to one system. Everything should be completely abstracted so that, if something on the backend changes, your code doesn't need to change.Which is an admirable goal, perhaps, but is also premature abstraction. For example, Mike's company uses Asterisk, an open-source PBX system. This co-worker wanted to script a few actions in that system, but didn't want his scripts to be tightly coupled to the system that he was scripting, so he… overgeneralized. But also didn't. But also did it wrong.Specifically, new voicemails needed to also get sent to an email address. Asterisk stores voicemails in the form msgNNNN.wav, where NNNN is a 0-padded numeric value, e.g. msg0123.wav.This is the PHP code to find the proper file to send:
Error'd: pop
Alas, I have only the following five submissions to share, as my controversy generator is on the Fritz today.Ex post autumnalAdam R. warmly reflects "I'm not quite sure how the math works out here, but I'm apparently a one-percenter in the home energy savings department."
CodeSOD: A Learning Opportunity
At various points in my career, I spent my days delivering technical training. If your company wanted to adopt a new technology, or upskill your developers, you'd hire me and I'd do crash course sessions. I generally didn't design course material: the books, slide decks, and labs. I just delivered the course. Most of the course material I worked with was pretty good, but there were some which were clearly written by people who were just trying to get a course out the door fast while a new technology was buzzwordy enough that nobody knew what they were buying.I hated those courses.All this means that we're going to shift gears a little bit into something we don't usually look at: the kinds of code that may be used as examples in training material.The first one comes from Jan, who was just trawling through JavaScript guides, and stumbled across one article that really stressed the importance of comments. For example, this incredibly complex method needs this comment attached to it:
CodeSOD: $art000
Many years ago, Brian was on the lookout for a new contract. While hunting, he found an opportunity to maintain some Intranet software for a large European news agency. He contacted them, and had a series of conversations with one of the managers."You see," the manager explained, "Sven was the code guru behind this entire system. He was… a colorful personality, but extremely smart. We don't have a lot of confidence that we could just slot a contractor into his role and expect them to be able to deliver what Sven could deliver for us."To give them that confidence, Brian agreed to do some very small contract work before they moved on to a larger, longer-term contract. This let him see exactly what Sven could deliver.
CodeSOD: Just A Temporary Thing
Daniel inherited some code which depends heavily on stored procedures. The person who developed those stored procedures was incredibly fond of overengineering things. Incredibly fond.The result is a big pile of not incredibly interesting T-SQL code. I'll share the whole block of code in a moment, but there's one specific comment that I want to highlight before we look at it:
Error'd: Some Like It Hot
Admittedly, this holiday season is culturally dominated by theAnglo-American tradition of a wintertime Christmas.Currier & Ives notwithstanding, most of the variousholidaysobviously originatedin some summer event, or else a harvest one. For these hot holidays,our mate Peter starts things off with a very warm greeting from down under. Following that are a few of myfavorite stocking stuffers, until Peter's antipodal ally Michael closes everything out with an appeal towarm the heart but not blister the sole.AussiePeter G. mutters weakly "Ithink this warning is bit superfluous (for the non-metric,that's 550 degrees F)."
CodeSOD: Stop, Watch
On one hand, we should all be doing our revision tracking in our source control system, and we shouldn't let code comments tell the story of why or how the code changed. On the other, when it leaves us the history of WTFs in the current version of the code, it's actually delightful.Take this anonymous submission, which includes the whole story of the code, all at once.
CodeSOD: Dummy Round
Different languages will frequently have similar syntax. Many a pointy-haired-boss has seen this similarity and thus assumed that, if their programmer knows C, then C++ should be easy, and if they know C++ then going into C# must be trivial. I mean, the languages look the same, so they must be the same, right? Boats and cars are steered by wheels, so clearly if you can drive a car you can pilot a boat, and nothing will go wrong.Andreas S inherited some code that started at C/C++ and was then ported to C#. The original developers were the sort to reinvent wheels wherever possible, so it's no surprise that they kept that going when they moved into C#.There are, for example, a few methods not supplied in today's code sample. They wrote their own RoundTo, which Andreas describes thus: "RoundTo() is basically equal to Math.Round(), but implemented in a WTF way." There is also a homebrew Sprintf implemented as an "extension method" on Strings.These all get combined in the method GetStringToRound which doesn't get anything, but seems to just format a string into a rounded off value.
Unseen Effort
Anita, a senior developer, had recently been hired at a company with around 60 employees. Her first assignment was to assist with migrating the company’s flagship on-premises application to the cloud. After a year of effort, the approach was deemed unworkable and the entire project was scrapped. Seem a little hasty? Well, to be fair, the company made more money selling the servers and licenses for running their application on-premise than they made on the application itself. Multiple future migration attempts would meet the same fate, but that's a whole other WTF.With the project's failure, Anita became redundant and feared being let go. Fortunately, the powers-that-be transferred her to another department instead. This was when Anita first met Henry, her new manager.Henry was a database guy. It wasn't clear how much project management experience he had, but he definitely knew a great deal about business intelligence and analytics. Henry explained to Anita that she’d be working on implementing features that customers had been requesting for years. Anita had never worked with analytics before, but did have a background in SQL databases. She figured multi-dimensional databases shouldn't be too hard to learn. So learn she did, working as a one-person army. Henry never put any time pressure on her, and was always happy to answer her questions. The only downside to working for him was his disdain toward open source solutions. Anita couldn't use any NuGet packages whatsoever; everything had to be built from scratch. She learned a ton while making her own JSON parsing library and working out OAuth 2.0 authentication.Upon completing a project, Anita would go to Henry's office to demo it. Once satisfied, Henry would say "Great!" and hand her a new project. Whenever Anita asked if there were a feature request logged somewhere that she could close out, she was told she didn't have to worry about it. She would also ask about her previous efforts, whether they'd been tested and released. Henry usually replied along the lines of, "I haven't had time yet, but soon!"Over time, Anita noticed an uncomfortable trend: every 12 months or so, the higher-ups fired 20-30% of the entire staff, normally from Sales or Marketing. The company wasn't making as much money as the shareholders thought it should, so they would fire people, wait a few months, then hire new people. For the most part, though, they spared the developers working on the core application. They were smart enough to understand that no one coming in cold would be capable of figuring out this beast.She figured she was safe—and yet, after 6 years, Anita found herself being fired. Henry brought her into his office, insisted it wasn't his choice, and emphasized that he was very sorry to lose her.Anita shook her head in resignation. After the shock had worn off, she'd looked into a few things. "Over the years, you gave me 8 projects to work on," she said.Henry nodded."Are you aware that you never tested any of them?" Anita asked. "You never released them to production. They're still sitting in SourceSafe, waiting for someone to use them. Are you aware that the company has never seen a penny from the work I've done for you?"From the look on his face, it was clear that Henry had never realized this."This has been a good learning experience, at least," Anita said. "Thanks for everything."Anita was able to take the knowledge she'd gained and double her salary at her next job, which only took 3 weeks to find. She's no longer reinventing the wheel or going unappreciated, and that's a win-win for sure. [Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.
Leading From Affronts
Scientists frequently need software to support their research, but rarely are strong developers. And why should they be, that software is written to accomplish a goal, and it's the goal which matters to them more than anything about the software itself.That's where Jared comes in. He worked in a university IT department and his job was simply to write the software the researchers needed. They frequently had a very clear picture of what they needed, along with big piles of math to explain it, plus piles of example input and expected output data.The team was small- just Jared and two other developers, Larry and Barry. There was no team lead, they could simply coordinate and divide the work. Their manager was nearly invisible, and mostly focused on keeping external office politics from disrupting the work. The work wasn't precisely simple, but it was clear and well defined, the pay was good.While the code quality wasn't perfect, it was good enough. Since throughput was one of the main drivers of the design, a lot of code segments got hyperoptimized in ways that made the code harder to understand and maintain, but boosted its performance. The software was mostly stateless, the unit test coverage was nearly 100%, and while the UI was the ugliest of ducklings, the software worked and gave the researches what they wanted.In short, it was the best job Jared had ever had up to that point.Six months into the job, Jared came into work as he normally did. Larry was an early starter, so he was already at his desk, but instead of typing away, he simply sat at his desk. His hands were in his lap, and Larry simply stared forlornly at his keyboard. Barry had a similar thousand-yard stare aimed at his monitor."What's wrong?" Jared asked.The answer was just a long sigh followed by, "Just… go pull the latest code."So Jared did. The latest commit eradicated everything. Most of the files in the codebase had been deleted and replaced with a single 7,000 line God Object. And the git blame told him the culprit, someone named "Scott"."Who the heck is Scott?"Larry just shook his head and sighed again. Barry chimed in. "He's our technical lead.""Wait, we got a new technical lead?" Jared asked."No, he's always been the tech-lead. Apparently. I had to check the org-chart because I didn't even know- none of us did. But Larry's worked with Scott before."That revelation caused Larry to sigh again, and shake his head."It apparently didn't go well," Barry explained.A little later that morning, Scott wandered into their team room. "Hey, Josh, you must be the new developer.""Jared, and I've been here for six months-""So, I noticed we'd gotten a little off track," Scott said, ignoring Jared. "I've been bouncing around a lot of different projects, because well, you know, when you're good people want you to do everything, and work miracles, amirite? Anyway, we're going to make some changes to improve code quality and overall design."So Scott walked them through his new architectural pattern. That 7,000 line God Object was, in part, an event bus. No object was allowed to talk directly to any other object. Instead, it needed to raise an event and let the bus pass the information to the next object. For "performance" each event would spawn a new thread. And since the God Object contained most of the application logic, most events on the bus were sent from, and received by, the God Object.As a bonus, Scott hadn't written any unit tests. There were more compiler warnings than lines of code- Scott's code averaged 1.3 warnings per line of code. And no, Scott would not allow anyone to revert back to the old code. He was the tech-lead, by god, and he was going to lead them.Also, 18-person months of work had just been deleted, all the new features that Jared, Larry and Barry had added over the past six months. Their end users were furious that they'd just lost huge pieces of functionality. Also, the multi-threaded "performant" version took hours to do things that used to take seconds. And within a few weeks of Scott's "revisions" the number of bugs tracked in Jira rose by a factor of six.The researchers did not like this, and simply refused to update to the new application. Scott did not like that, and started trying to force them to change. Their manager didn't like any of this, and pressured the team to fix the new version of the application. And quickly, which meant a lot of unpaid overtime. Once overtime started, Scott "surprisingly" got pulled into another project which needed his attention.With Scott gone, they were almost able to revert to the old version of the code, but there had been so much work put into the new version that their manager only saw the sunk costs and not the bigger picture. They were committed to sinking the ship, whether they liked it or not.Bug counts kept rising, it got harder and harder to implement new features, there was a scramble to hire new people and the team of three suddenly became a team of twelve, but nothing could be done for it. The system had become an unmaintainable Codethulhu.The best job Jared had ever had turned into the worst, all with one commit from Scott. Jared quit and found a new job. Scott kept plugging away, vandalizing codebases in the university for another five years before finally screwing up big enough to get fired. The last Jared saw on LinkedIn, Scott had moved on to another, larger, and more prestigious university, doing the same development work he had been doing. [Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.
Error'd: The Other Washington
This week, anonymous Franz starts us off with a catch-22."I opened MS Word (first time after reboot) and a dialogbox opens that tells me to close a dialog box. This wasthe only open dialog box... I guess even software makesexcuses to be lazy on Fridays."
CodeSOD: A Split in the Database
Oracle is… special. While their core product is their database software, what they actually sell is layers and layers of ERPs and HR systems that run on top of that database. And what they really make money on is the consulting required to keep those monsters from eating your company's IT team alive.Because these ERPs are meant to be all things to all customers, you also will find that there are a lot of columns named things like attribute3. Your company's custom logic can stuff anything you want in there. "Do as thou wilt," as they say. And suffer the consequences.For Steven H, his company had a requirement. The order lines needed to join to the manufactured batch that was used to fill that order. This makes sense, and is easy to implement- you add a join table that links BatchId and OrderLineId And, if the folks who build this feature did that, we wouldn't have an article.To "solve" this problem, they simply mashed together all the order line IDs fulfilled by a batch into a text field called attribute7. The data looked like:413314|413315|413329That fulfilled the requirement, in someone's mind, and the ticket was closed and folks moved on to other work. And then a few years later, someone asked if they could actually display that data on a report. It seemed like a simple request, so it got kicked off to an offshore team.This was their solution:
CodeSOD: Two Comparisons, Hold the Case
There are a lot of times when we want string comparisons to be case insensitive. It's quite a lot of cases, so every language is going to give us a way to easily specify that's what we want.Take, for example, this C# code, written by one of Robin's team-mates.
CodeSOD: Filtering Out Mistakes
We all make simple mistakes. It's inevitable. "Pobody's nerfect," as they say, and we all have brain-farts, off days, and get caught up in a rush and make mistakes.So we use tools to catch these mistakes. Whether it's automated testing or just checking what warnings the compiler spits out, we can have processes that catch our worst mistakes before they have any consequences.Unless you're Jose's co-worker. This developer wasn't getting any warnings, they were getting compile errors. That didn't stop them from committing the code and pushing to a shared working branch. Fortunately, this didn't get much further down the pipeline, but said co-worker didn't really understand what the big deal was, and definitely didn't understand why there were errors in the first place.In any case, here were the errors tossed out by the C# compiler:
CodeSOD: Are You Doing a Bit?
"Don't use magic numbers," is a good rule for programming. But like any rule, you shouldn't blindly apply it. We know what happens when people do, however: we get constants that might as well be magic numbers.Still, there are sometimes novel versions of this old song. Shmuel F sends us this one in C:
Error'd: The Scent of a Woman
While Error'd and TDWTF do have an international following, andthis week's offerings are truly global, we are unavoidably mired in American traditions.Tomorrow, we begin the celebration of that most-revered of all suchtraditions: consumerist excess. In its honor, here are a half-dozenexemplary excesses or errors, curated from around the globe. They'renot necessarily bugs, per se. Some are simply samples of thatother great tradition: garbage in.Opening from Poland,Michal reported recently of a small purchase that"The estimated arrival was October 27th. But, for a not-so-small additionalfee, AliExpress offered to make an extra effort and deliver it as soon as... November 3rd."
Classic WTF: When Comments go Wild
CodeSOD: Counting Arguments
Lucio C inherited a large WordPress install, complete with the requisite pile of custom plugins to handle all the unique problems that the company had. Problems, of course, that weren't unique at all, and probably didn't need huge custom plugins, but clearly someone liked writing custom plugins.One of those plugins found a need to broadcast the same method invocation across a whole pile of objects. Since this is PHP, there's no guarantee of any sort of type safety, so they engineered this solution:
CodeSOD: Templated Comments
Mike's company likes to make sure their code is well documented. Every important field, enumeration, method, or class has a comment explaining what it is. You can see how much easier it makes understanding this code:
CodeSOD: A Sort of Random
Linda found some C# code that generates random numbers. She actually found a lot of code which does that, because the same method was copy/pasted into a half dozen places. Each of those places was a View Model object, and each of those View Models contained thousands of lines of code.There's a lot going on here, so we'll start with some highlights. First, the method signature:
Error'd: Largely middling
Jani P. relates "I ran into this appropriate CAPTCHA when filling out a lengthy, bureaucratic visa application form." (For our readers unfamiliar with the Anglo argot, "fricking" is what we call a minced oath: a substitute for a more offensive phrase. You can imagine which one - or google it.)
CodeSOD: Efficiently Waiting
Alan was recently reviewing some of the scriptlets his company writes to publish their RPM installers. Some of the script quality has been… questionable in the past, so Alan wanted to do some code review.In the uninstallation code, in the branch for AIX systems specifically, Alan found a block that needs to check that a service has successfully shut down. Since properly shutting down may take time, the check includes a pause- implemented in an unusual way.
A Binary Choice
As a general rule, don't invent your own file format until you have to, and even then, probably don't. But sometimes, you have to.Tim C's company was building a format they called "generic raw format". It was solving a hard problem: they were collecting messages from a variety of organizations, in a mix of binary and plaintext, and dumping them into a flat file. Each file might contain many messages, and they needed to be able to split those messages and timestamp them correctly.This meant that the file format needed a header at the top. It would contain information about byte order, version number, have space for arbitrary keys, and report the header length, all as text, represented as key/value pairs. Then they realized that the some of the clients and vendors supplying this data may want to include some binary data in the header, so it would also need a binary section.All of this created some technical issues. The key one was that the header length, stored as text, could change the length of the header. This wasn't itself a deal-breaker, but other little flags created problems. If they represented byte-order as BIGENDIAN=Y, would that create confusion for their users? Would users make mistakes about what architecture they were on, or expect to use LITTLEENDIAN=Y instead?In the end, it just made more sense to make all of the important fields binary fields. The header could still have a text section, which could contain arbitrary key/value pairs. For things like endianness, there were much simpler ways to solve the problem, like reserving 32-bits and having clients store a 1 in it. The parser could then detect whether that read as 0x00000001 or 0x10000000 and react accordingly. Having the header length be an integer and not text also meant that recording the length wouldn't impact the length.These were all pretty reasonable things to do in a header format, and good compromises for usability and their business needs. So of course, Blaise, the CTO, objected to these changes."I thought we'd agreed to text!" Blaise said, when reviewing the plan for the header format."Well, we did," Tim explained. "But as I said, for technical reasons, it makes much more sense.""Right, but if you do that, we can't use cat or head to review the contents of the file header."Tim blinked. "The header has a section for binary data anyway. No one should be using cat or head to look at it.""How else would they look at it?""Part of this project is to release a low-level dump tool, so they can interact with the data that way. You shouldn't just cat binary files to your terminal, weird stuff can happen."Blaise was not convinced. "The operations people might not have the tool installed! I use cat for reading files, our file should be catable.""But, again," Tim said, trying to be patient. "The header contains a reserved section for binary data anyway, the file content itself may be binary data, the entire idea behind what we're doing here doesn't work with, and was never meant to work with, cat."Blaise pulled up a terminal, grabbed a sample file, and cated it. "There," he said, triumphantly, pointing at the header section where he could see key/value pairs in a sea of binary nonsense. "I can still see the header parameters. I want the file to be like that."At this point, Tim was out of things to say. He and his team revised the spec into a much less easy to use, a much more confusing, and a much more annoying header format. The CTO got what the CTO wanted.Surprisingly, they ended up having a hard time getting their partners to adopt the new format though… [Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
CodeSOD: A Select Sample
"I work with very bad developers," writes Henry.It's a pretty simple example of some bad code:
CodeSOD: It's Not What You Didn't Think it Wasn't
Mike fired up a local copy of his company's Java application and found out that, at least running locally, the login didn't work. Since the available documentation didn't make it clear how to set this up correctly, he plowed through the code to try and understand.Along his way to finding out how to properly configure the system, he stumbled across its logic for ensuring that every page except the login page required a valid session.
Error'd: Any Day Now
This week at Errr'd we return with some of our favorite samples.A screwy message or a bit of mojibake is the ordinary thing; the realgems are the errors that are themselves error dialogs.We've got a couple of those, and a few of the ordinary sort.Stealing the worm, pseudoswede Argle Bargle comments "Generally,Disqus works well. I can even imagine the borderconditions that cause my time-travel glitch. I'm even gladthat the programmers planned for... for just such an emergency.Maybe it's even good programming. It's still very silly."
CodeSOD: Giving Up Too Late
"Retry on failure" makes a lot of sense. If you try to connect to a database, but it fails, most of the time that's a transient failure. Just try again. HTTP request failed? Try again.Samuel inherited some code that does a task which might fail. Here's the basic flow:
CodeSOD: Delete Column From List
Anastacio knew of a programmer at his company by reputation only- and it wasn't a good reputation. In fact, it was bad enough that when this programmer was fired, no one- even people who hadn't met them- was surprised.The firing wasn't all good news, though. That code needed to be maintained, and someone had to do it. That's how Anastacio suddenly owned 50,000 lines of code written by his predecessor. It didn't take long to see that this didn't need to be anything like 50,000 lines long, though.For example:
CodeSOD: Bad Code Exists
It's time to round up a few minor WTFs today. Some are bad, some are just funny, and some make you wonder what the meaning of all of this actually is.We'll start with Tom W. After winning a promotional contest at a fast food restaurant, he received a confirmation email. Unfortunately, at the top of that email, was the following content in plaintext:
CodeSOD: Bop It
Over twenty years ago, Matt's employer started a project to replace a legacy system. Like a lot of legacy systems, no one actually knew exactly what it did. "Just read the code," is a wonderful sentiment, but a less practical solution when you've got hundreds of thousands of lines of code and no subject-matter experts to explain it, and no one is actually sure what the requirements of the system even are at this point.There's a standard practice for dealing with these situations. I'm not sure it should be called a "best practice", but a standard one: run both systems at the same time, feed them the same inputs and make sure they generate the same outputs.We cut to present day, when the legacy system is still running, and the "new" system is still getting the kinks worked out. They've been running in parallel for twenty years, and may be running in that state for much much longer.Matt shares some C code to illustrate why that might be:
Error'd: Lost In Translation
No, it's generally not nice to pick on people who fumble a second language. But TDWTF isn't here to be nice, it's here to be funny, or at least interesting.If nothing else, our final submission this week qualifies as interesting, after you go haring off downthe trail of ambient context following your kreiselkompass.We start with an anonymous submission from a reader who writes "The English in this config dialog isn't great so I guessI'll play the game in the alternate language, Ҝ-{ΐ." Personally, I'd stick with Hyphen.
CodeSOD: A Replacement Operation
Apolena supports an application written by contractors many years ago. It tracks user activity for reporting purposes, as one does. They then want to report on this, because why else are you gathering this information?The contractor supplied this query to do the work.
CodeSOD: Unable to Focus
We've talked about Microsoft's WebForms in the past. Having used it extensively in the era, it was a weird mismatch, an attempt to get Visual Basic-style GUI designer tools attached to web applications, where button presses on the client side web page were exposed as events on the server side.It also meant that you could manipulate the GUI objects on the server side, and the rendered HTML would represent that. So as part of processing a request, you might manipulate one of these "server side" controls. So, if you wanted to ensure that the search field had focus when the page loaded, you could simply invoke txtSearch.Focus() as part of handling the request.Since you may still need to do something on the client side at page load, like maybe register run some jQuery calls to turn a text box into a fancy date picker wideget, it also offered a ScriptManager.RegisterStartupScript. This executes some JavaScript when the page loads.If all of this sounds bad, and like it's the real WTF, you're absolutely right. But even in this terrible world, you could still make things worse.Ino sends this:
CodeSOD: Contractor's Leftovers
There once was a developer who had a lot of hustle. They put out a shingle as a contractor, knocked on doors, made phone calls, and targeted those small businesses that needed something a little more custom than just off-the-shelf could get, but didn't have the money to afford a larger dev shop.And after finishing a handful of projects and building a reputation, this developer took a job at a large firm, in another town, and left a lot of unhappy customers with unfinished software behind.This is where Graeme comes in. He got a call from a local hotel who needed their booking system finished up. It had some… colorful choices.
CodeSOD: A Repetition of Repetition to Repeat
Inheritance is often described as a tool for code reuse, and those discussions inevitably wander down an alley parsing out the nature of has a and is a relationships, when to favor composition, and how inheritance trees get fragile.When Megan D inherited a Java application which had been largely untouched since 2006, she expected it to be full of all kinds of ugly problems. But they couldn't be that ugly- the software was used and well liked by the end users. Of course, it was hard to tell if they actually liked it, or had just been with it so long they'd adjusted to its flaws, because the whole workflow was extremely fragile and frequently failed.One feature in the large application was a reporting subsystem which could display line graphs. The three classes we'll look at form a nice inheritance hierarchy. There is the LineGraphTableModel, and then specifically the XLineGraphTableModel and the YLineGraphTableModel.These classes exist to let the user configure the way the graph renders. The user interface displays the options that can be set for each axis in a JTable view. Each data series on the graph gets a row in the table, each setting you can control on the data series gets a column.The first thing we'll highlight is that LineGraphTableModel contains a enum called TableColumns, which are the columns on our table.
Error'd: Is This The Real Life
To atone for last week's errant Error'd, this week we're giving you 20% extra at no additional charge. For reals.Ananonymous submission starts us off. Ordinarily we wouldn't repostfrom social media but this is just too delicious.
CodeSOD: Users That Bug You
I frequently write bad code. I mean, we all do, but I frequently write bad code with full knowledge that it's bad, because I first want to test out an idea. Or, I want to inject some additional behavior just for one run, because I'm trying to debug something. If that idea or debugging hook turns out to be valuable, I'll frequently refactor it into something useful and enable it via a flag or something.Which brings us to the crash Doug was investigating in a VB.Net application. For some reason, the username field was an empty string after logging in, and a bunch of methods which expected the username to have a value misbehaved after that.Well, one of the debugging hooks was turned on, and it called GetReplacementUser, which… is interesting.
Committed Database
Database administrators tend to be pretty conservative about how databases are altered. This is for good reason- that data is mission critical, it's availability is vital, and any change you make threatens that stability and reliability. This conservatism ranges from "we have well defined processes for making changes" all the way to "developers are dangerous toddlers playing with guns and we can't allow them to do anything lest it break our precious database.""Grumpy" Gus worked with some DBAs that fell much more on the "developers can't be trusted" end of the spectrum. This meant they had big piles of rigorous processes to make sure only the most important, definitely required changes to the database ever got made. The process involved filing several documents, marking an entry on a spreadsheet, emailing a dba@initech.com inbox, and then waiting. Your request would snake its way through a Database Management Subcommittee, then get kicked over to a Business Need Evaluation Working Group. If the working group agreed that this change met a level of business need, it went back to the subcommittee, which reviewed the findings and if they agreed escalated it to the monthly Database Administration Steering Committee and Database Users Group meeting. Once again, it would get reviewed. If accepted, the DBAs could write a change script, and apply it in the next database maintenance window.From start to end, the process took a month, if not longer, and your request could be kicked back at any step in the process. If you didn't fill out the initial documents in the correct order, and to the satisfaction of the groups, down to using, commas, correctly, it could be rejected. You may or may not be told why.All this created a problem: the "big boss" wanted three new boolean fields in the database, and wanted it yesterday. There was no guarantee that the committees would even let Gus finish the process. And it was impossible to get it done in any sort of timely fashion.But Gus was smart, creative, and aware that the FAX_PHONE_NUMBER field on all of their customer records were blank. Gus couldn't change the schema, but he could change the way his application used the database fields.
CodeSOD: Patching Over Your Problem
Deanna inherited some code which had gone through many, many previous hands. Like a lot of JavaScript/TypeScript code, it needed to be able to compare objects for deep equality. This is fraught and complicated, and there are many many many solutions available in NPM.NPM, of course, is its own fraught thing. Widely used libraries frequently have vulnerabilities, and even if you don't use them directly, the nature of dependency management via NPM means that libraries your libraries depend on might.If you want to avoid that, you could whip up your own deep equals function, with a little recursion. Or, if you're a real hack, you might gamble on JSON.stringify(a) == JSON.stringify(b) working (which is a gamble, as it depends on key insertion order being the same).Deanna's predecessors found a different solution. They did go off to use a library- but the library they chose is a bit surprising for this task.
CodeSOD: Read the Comments
Many many years ago, when I took my first programming course in high school, our instructor had… opinions. One of those opinions was that you should manually syntax check your code and not rely on compiler errors, because back in her day, you had to punch your program into cards, drop it off in the computer lab, wait for the technician to run your batch, and then pick up the results on the printer. It needed to work the first try or you might be waiting a whole day before you could try again.One of her other opinions was that your code should contain as many comments as it contained lines of code. Everything needed comments. Everything. Which brings us to this code from Doug.
Error'd: Outages, Prices, and Catastrophe
Shaun F noticed an outage."Maybe," Shaun writes, "they should use the Cloudflare Always Online service."Meanwhile, at Subway, Maurice R has found the deal of a lifetime.And as we get into Autumn, Lincoln Ramsay warns you to be on the lookout for sudden cold snaps. [Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!
Performance Tuning for Exabyte Queries
While NoSQL databases have definitely made their mark and have an important role in applications, there's also still a place for RDBMSes. The key advantage of an RDBMS is that, with a well normalized schema, any arbitrary query is possible, and instead of optimizing the query, you optimize the database itself to ensure you hit your performance goals- indexes, statistics, materialized views, etc..The reality, of course, is wildly different. While the execution plan used by the database shouldn't be dependent upon how we write the query, it frequently is, managing statistics and indexes is surprisingly hard, and when performance problems crop up, without the right monitoring, it can be difficult to track down exactly which query is causing the problem.Which brings us to this query, which TJ found while analyzing a performance problem.
CodeSOD: A Ritual Approach
Frequent contributor Russell F stumbled across this block, which illustrates an impressive ability to make a wide variety of bad choices. It is written in C#, but one has the sense that the developer didn't really understand C#. Or, honestly, programming.
CodeSOD: Low (Quality) Code
Like the tides, the popularity of low-code development environments comes in ebbs and flows. With each cycle, the landscape changes, old tools going away and new tools washing up on shore. One one hand, democratizing access to technology is good, on the other, these tools inevitably fail to actually do that. Instead, we get mission critical developed by people who don't understand how to develop, and are thus fragile, and released on platforms that are almost certainly going to be on legacy support in the next cycle.I don't want to imply that low-code tools are automatically bad, or insult non-developers who want to give developing in a low-code environment a shot, though. Especially when professional developers can't really do any better.John F's company has adopted one of the new tools in this cycle of low-code tools, Microsoft Power Apps, using the Power FX scripting language. One of the screens in their application needs to display a table of sales data, organized by month. This is how one of their developers decided to generate the list of months to draw:
...12131415161718192021...