Rust is one of the "cool" languages these days. It promises all the low-level power of C with memory safety and "modern" programming conventions like iterables and maps. High performance, expressive language, low-level power seems like a great combination for certain domains.Now, Jenna Winchester needed to do some Morton Coding or Z-indexing, which is an algorithm which lets you take multidimensional points and turn them into 1-dimensional points in a way that maintains their spatial relationships- essentially a fast way of traversing a quadtree. It's a fairly simple and fast algorithm, especially if you implement it using bitwise operations. A naive implementation, without optimizations, can do its job with very few CPU cycles, relatively speaking.And while Jenna could have implemented her own version of it, never reinvent a wheel that someone else probably has. So she tracked down a Rust library (or crate, if we're using Rust terminology) which promised to do the job. Jenna's expectation was that she could feed in her 5-dimensional point, and get back the z-index by simply doing something like let output = input.z_index(). Let's call the library morty_code, because we should focus more on the painful experience of working with a badly designed API than worry about calling out a library for a mildly niche language for a very specific problem domain.That, of course, would be too easy. The code which Jenna needed to write to perform the core purpose of what the library claimed to do was this:
Nearly 15 years ago, fresh out of college, Giuseppe was hired on at a mobile networking company. The company wasn't a software company, but since they were heavy in networking and could handle all sorts of weird technical problems there, software must basically be the same thing, so they also started producing applications to manage those networks.It didn't take them long to discover that "building networks" and "writing software" are different skillsets, and so they did what every company with some room in the budget does: they hire a pack of Highly Paid Consultants to get their project on track.Giuseppe joined the team just as the budget for consultants ran out. They "knowledge transfered" "everything" in a whirlwind of incomprehensible PowerPoint presentations, and then vanished back into whatever lairs HPCs come from, and left Giuseppe and the other new hires to figure out what was going on.When the HPCs were hired, the company had extensively specified the requirements. Each requirement was expressed in terms like:
"Hey," someone on Russell F's team said. "We should add some keyboard navigation to our web app." That struck everyone as an "easy win", specifically because they were really talking about making "enter" and "escape" do something useful.They wrote some quick requirements, passed it off, and the developer submitted a surprisingly long pull request. Russell passed a sample of three out of the dozens of methods:
Mandi didn't plan to take a staff job at a university. To the contrary, she'd heard some bad things: loads of office politics, budgets so thin you need quantum mechanics to describe their position, and bureaucracy thick enough to drown any project.But one day, she met her old colleague Scot for lunch, and they got to chatting about his university job. "Oh, yeah, that's common enough," he said, "which is why my team isn't structured that way. We're doing in-house development of educational solutions, which is a fancy way of saying 'nobody understands what we do, so they leave us alone'."Scot invited her to take a tour of his office, meet some of his co-workers, talk a little about the work they were doing. They were based in a rented office just at the edge of campus, sharing the floor with a few scrappy startups. It wasn't a fancy space, and it was a little cramped, but the first and last thing Mandi noticed was how happy everyone was to be there.Augusta, the front-end lead, talked a little about their framework selection process, and how they made their choices, not based on what was new and trendy, but based on what felt like a really good fit for their subject matter. Harry, who handled the middleware, was happy to explain how he'd needed some time to get up to speed on the right cloud scaling options, but the team was there to support him, and they eventually got a great set of automation built which handled spikes but kept costs down. Quinn rhapsodized about how great it was to work closely with the end users, to really build the solution that worked best for them, and how exciting it was to see their requirements translate into implemented software with tangible benefits.Unlike pretty much any place Mandi had ever seen, everyone was happy to be there. Everyone liked the work they were doing. Everyone felt empowered to make the best choices, to work through challenges with the rest of the team, and everyone enjoyed celebrating their successes together."I always have to bring people in," Scot said, "because nobody believes me when I tell them about how great my job is.""Honestly, I still don't believe it," Mandi said."Well, I did have a bit of an ulterior motive. We're looking to scale up the team a bit, which means I'll have a position soon. It'll take a little bit to grind those gears- that has to go through the university hiring process, but I hope you apply. I think you'd be a great fit."Mandi did apply, when the position finally opened up. It was a slow-moving interview process, mostly through the university HR department, but she met Scot one more time, early in the process. Then, she landed the job, a contract-to-hire position.At that point, Scot didn't work there anymore. He had resigned, and since the team was actively working, and since the HR process was painfully slow, the HR department didn't hire a replacement as an employee- they hired a contractor. Technically, Mandi worked under the same contract, and thus her direct manager was Cyril, the new team lead.There was just one problem with that: by both university policy and IRS rules, contract employees can't manage regular employees. So Cyril's title was just "scrum master", and he technically had no management authority. Which meant the regular employees ignored him.Mandi and one other contractor reported to Cyril, but nobody else did.The overall project lead, Ruthie, was also a contractor, but hired through a different contracting firm. Not only did she have no authority over regular employees, she had no authority over any other contractors. Nobody reported to her, but she was in a management role.The result of this management omni-shambles was meetings. Loads of meetings. Daily standups became daily "take a load off, we'll be here awhiles". After the standup, Cyril would be pulled into meeting after meeting as every section of the department started pulling in different directions, so despite being the "scrum master", he had no idea what anyone on the team was doing. Ruthie threw meetings on everyone's calendar, which nobody attended, because nobody worked for Ruthie. The only way for a contractor to get a regular employee's attention was to schedule a meeting.Above both Ruthie and Cyril was the technical lead for the entire campus IT department. He was the only person in the org chart that everyone technically reported to, but he had never been a fan of the entire "rent an off campus office and let smart people solve problems," approach. While he was the only one who could potentially set some direction, he had no interest in doing so. The one time Mandi was on a conference call with him, he excused himself, "This isn't really a priority for me right now, I have other issues I need to address that are more important."Mandi stuck it out until the end of her contract period. She never received an offer for a full-time position, and frankly, she wouldn't have taken it anyway. Her fellow subcontractor, the only other person who reported to Cyril, did. So his HR hiring process can work, eventually, for some people. [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
If you've worked with developing software of any real complexity, you've probably come across a library or tool that does code generation. Instead of writing all the boring boiler-plate stuff yourself, you maybe throw a little configuration at the system and let it generate all those classes for you. I'd argue that, in most cases, that sort of thing is a code smell- it's not in and of itself bad, but it hints as missed abstractions. There's probably a general way to represent what you want to represent without generating a big pile of classes. The question is: is the additional abstraction worth it, or should you just generate code to get it done?Russell was recently browsing the documentation for Amazon Web Services. The Java SDK allows you to send requests to AWS to automate things in their cloud. When you send a request, you need an AmazonWebServiceRequest object. Now, AmazonWebServiceRequest is itself an abstract class, so we need to send a concrete implementation, specific to the operation we want to perform. That means it's going to be one of:
Thanks again to everyone who submitted a holiday tale for our What the Fun Holiday special. Like all good holiday traditions, our winner indulges in a bit of nostalgia for a Christmas classic, by adapting the classic "A Visit From St. Nicolas", a trick we've done ourselves. But like a good WTF, Lee R also mixes in some frustration and anger, and maybe a few inside jokes that we're all on the outside of. Still, for holiday spirit, this tale can't be beat.Now, our normal editorial standards avoid profanity, but in the interests of presenting the story as Lee submitted it, we're going to suspend that rule for today. It is, after all, the holidays, and we're all miserable.In December 2018, our distributed Sports app team at FOX was to the wall. We needed to release a new version with pay-per-view streaming before an immovable sporting event date in Q1. I frequently explained away my bugs and other failures by blaming our cats, since they walk on the keyboard and "write the code."I decided the team needed to loosen up and (again blaming the "codin' cats") posted the following on our main dev Slack channel right before Christmas break.
As we roll into the last few days before Christmas, it's time to share what our readers sent in for our "What the Fun Holiday" contest. It was a blast going through the submissions to see what our holiday experiences looked like.Before we dig in to our contest winners, our first honorable mention is to David N, who shared with us "The Worm Before Christmas", a classic from 1988 that was new to us.Our first runner up story comes from Mike. This is an Easter Tale, complete with a death, a resurrection, and thirty pieces of silver (or whatever amount you give highly paid consultants).
Dora's AngularJS team (previously) wanted to have their display be "smart" enough to handle whether or not you were editing a list of "Users" or just one "User", so they implemented a function to turn a plural word into a singular word.Which, of course, we already know the WTF implementation of it: they just chop off the last letter. So "Potatoes" becomes "Potatoe", "Moose" becomes the noise cows make, and I'm just left saying "oh, gees". But they managed to make it worse than that.The actual display might be used like so:
Web frameworks are a double edged sword. They are, as a rule, bloated, complicated, opinionated and powerful. You can get a lot done, so long as you stick to the framework's "happy path", and while you can wander off and probably make it work, there be dragons. You also run into a lot of developers who, instead of learning the underlying principles, just learn the framework. This means they might not understand broader web development, but can do a lot with Angular.And then you might have developers who don't understand broader web development or the framework they're using.Dora has someone on their team which meets that criteria.The first sign there was a problem was this line in a view object:
One of the best parts of doing software development is that you're always learning something new. Like, for example, I thought I'd seen every iteration on bad date handling code. But today, I learned something new.Katharine picked up a pile of tickets, all related to errors with date handling. For months, the code had been running just fine, but in November there was an OS upgrade. "Ever since," the users complained, "it's consistently off by a whole month!" This was a bit of a puzzle, as there's nothing in an OS upgrade that should cause date strings to be consistently off by a whole month. Clearly, there must be a bug, but why did it only now start happening? Katharine pulled up the C code, and checked.
Would you like to guarantee your project ends up on this site? Antoon's employer has a surefire technique. First, hire a freshly graduated architect with no programming experience. Second, chuck them into a project in a programming language they don't know. Third, give them absolutely no supervision and no guidance or support, and watch what happens.
There is no task so simple that a developer can't find a harder, more wasteful, and pointless way to do it. For example, let's say you want to know how many rows are in a data grid object?Hans found this C# snippet in production a few years ago:
Scott was new to the team, and so when a seemingly simple bug came in, he picked up the ticket. It should be an easy win, and help him get more familiar with the code base.The reported problem was that a user entered the time, and saved it. Several screens later, when that time was redisplayed, it was incorrect, off by some number of hours. Clearly, it was a small timezone issue, which should be easy to fix.Except that was easier said than done. Scott's company made a hosted service, and quite reasonably, each customer had their own database instance. But they also all had their own branch in source control. That's where things started to get problematic, as there was no coherent naming convention, each customer's version had its own customization and a blend of merges and cherry-picked commits that made it impossible to, at a glance, understand what was or wasn't deployed to any given branch.Once Scott figured out which branch to use, he stood up a simulation environment and tried to replicate the error. He entered the date. He checked the database- the date was stored correctly. He went to the screen which was incorrect, and saw that it was off- though by a totally different number of hours than the customer reported. On a different screen, however, the date displayed correctly. Digging through the code, the incorrect screen was adjusting the timezone from UTC to the local timezone, while the correct screens weren't doing any timezone adjustment.Confused, Scott went to his boss, Zofia. "I assume it's doing the adjustment when it shouldn't, but I'm just confused by why it's doing that?"Zofia sighed. "Because a very long time ago, I let the owner talk me into a very bad idea. We don't store timezone information with the times. Most of the time, we convert them to UTC and store that, and then convert to the local timezone on display. But because we were in a 'move fast and break things' phase, we didn't do that with all of our times. Some we just store in the local timezone- without storing any timezone info."The result is that a timestamp, stored in the database, might either be in the local timezone of the person who created the record, or might be in UTC, but you couldn't tell which by looking at the database. So you had to check the code which handled the storage and display. That code was in a twisted network of git branches, so for any given customer, the rules might be utterly different, and since commits were sometimes cherry-picked across branches (as a useful feature for one customer becomes useful for another), the rules might suddenly change if you weren't careful."Oh… that's… horrifying."Zofia nodded. "You think that's bad, keep in mind that our reporting engine is a third party product that doesn't use the branching structure we set up in git. One change to dates in the application could mean you spend the next few days tracking down every reference to it and making sure you're only making changes that impact the one customer and nobody else.""I… maybe I should pass this ticket off to someone else?" Scott was certainly a lot less interested in tackling this "simple" bug."Nah," Zofia said. "It'll be a good way to learn the codebase. This is what we do every day." [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
Sometimes, our readers send us a story. Sometimes they send us some bad code. Sometimes, they just need a place to vent their frustrations. Paul T had some frustrations. Paul's team is migrating from .Net to .NetCore, and as one might imagine, that creates a lot of build failures.Their Team City build environment sometimes doesn't give the most helpful messages:
The power of a good devops team is that you can get fast, reliable, and repeatable deployments. It lays out a foundation for rapid iteration and quick releases. With that in mind, Lakeisha was pretty excited to start a new job working in devops.She walked in the door, with visions of well architected, scripted flows, robust automated testing, and strict architectural guidelines. About fifteen minutes in, she learn that FISI guided their entire devops workflow. If it worked, it worked.A few years back, someone had discovered MuleSoft's devops solutions and their "enterprise service bus". The ESB lets developers define "flows", which describe how messages pass between components in a large-scale, complex application.That much was fine, but no one on the team decided to learn how to do things in Mule's tools. Any time there was a new requirement, someone would say, "We can build a Mule flow for that!" They'd then dig through the existing flows for any similar components, copy-and-paste them in a new order to create their new flow, and once it looked like it mostly worked, deploy it and move on.Flows are designed in a graphical editor, but persisted as XML. Lakeisha sent us a block of common exception logging code, copy-and-pasted into every single flow.
CorpCo was a small company; it consisted of Tymeria, the president, and two programmers, Kylie and Ronnie. Kylie had seniority, having been working there for 6 or 7 years, but Ronnie, our submitter, had been working there a hefty 4 years herself. The company purchased a legacy VB web app from a client company, AClientCompany; AClientCompany had been working on the app for 15 years, with their lead programmer Michelle as the sole programmer. The app had been written in classic ASP using VBScript, though at some point Michelle had begun converting the project to ASP.NET with VB.NET. (Did you know you can mix and match classic ASP with ASP.NET and classic VBScript with VB.NET in the same solution? I didn't!). Of course, the app was riddled with security vulnerabilities, copypasta, and spaghetti code. One main class, called DBFunctions.vb, was over 30,000 lines!Fast forward to September 2019, shortly after CorpCo took over. The application involved multiple forms that customers had to fill out, some of which had customizable fields that the users could adjust on the fly. All of this was stored in a SQL Server database, hence DBFunctions.vb, the functions needed to pull data out of the database and render the forms for customers to enter and/or edit the forms by the internal users. A feature request came in to be able to mark some of the additional fields mandatory for completing the form: pretty basic stuff for a forms editor at heart. Ronnie wasn't familiar with the code, so she budgeted 13 story points, or just under a week.Before any of us dig into the code behind a project, we have certain basic assumptions about what we're going to find. Probably, form fields are stored in the database. Probably, there's a table for additional fields to which Ronnie could add a column in order to mark the field mandatory or optional. Probably, there's some identifier that marks the field as belonging to a specific form, and maybe even one for the order in which the questions go on the form so that order can be preserved. You know. Normal stuff.If those assumptions held up, we wouldn't be running this story, would we? As it turned out, instead of one AdditionalField table in the database, there were about 20 of them, one for each question type in the system. Why had Michelle done it this way? When Ronnie shot her an email, she replied sheepishly that she was concerned about the table getting to be "too big." "We don't want to get into big data territory," she said, proving that she knew nothing about big data and very little about databases.But whatever. Ronnie added a Mandatory column to each of the tables, updating all the SQL queries that were hardcoded inline without parameterization in the DBFunctions.vb file. Then she added a checkbox on each of the additional field edit screens, one for each type of question. She added JavaScript validation to the fields, though some of them (the checkbox lists in particular) didn't play nice with jQuery's validator, so she had to add custom code for those boxes. So finally, she finished, sat back, and ran the program to do her basic developer sanity checks.And ... it didn't work. The checkbox showed up, but checking it seemed to do nothing.Her code was still all in a branch at this point, so she wasn't holding anything up by fiddling with it. So she spent the rest of the week fiddling, trying to figure out what she missed. But it still wasn't quite working. She asked Kylie to look at the code, but Kylie had literally never used VB before, having been primarily a C#.NET developer. She asked Tymeria, but she was too busy with other projects to spend much time looking at it. So there wasn't much help to be had.And so the branch just ... rotted.It's now the end of 2020, over a year since the feature was requested. The branch is still languishing, rotting away. There's only a few bugs at this point, but nobody's able to quite figure them out and there's no more help to be had. There's been numerous other bug fixes and feature requests, and the code's been cleaned up a bit and a refactor is in the works. There's even an experimental branch where they imported a bunch of C# code to replace some of the worst bits of VBScript. But this branch is still sitting out there, languishing. Will CorpCo ever finish the feature request? Maybe.Probably not. But maybe.Only 3 days left before the auto-closer closes the ticket as "stale" ... [Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.
You've got one week left to teach us the real meaning of WTFmas. What's your holiday tale that we'll revisit winter after winter?Can you teach us the true meaning of WTFMas?What We WantWe want your best holiday story. Any holiday is valid, though given the time of year, we're expecting one of the many solstice-adjacent holidays. This story can be based on real experiences, or it can be entirely fictional, because what we really want is a new holiday tradition.The best submissions will:
A few months ago, Lee was reviewing a pull request from Eddie. Eddie was a self-appointed "rockstar" developer. Eddie might be a "junior" developer in job title, but they're up on the latest, greatest, bestest practices, and if everyone would just get out of Eddie's way, the software would get so much better.Which is why the pull request Lee was looking at touched nearly every file. Every change was some variation of this:
It was Paramdeep's first corporate IT job. He was assigned a mentor, Rajiv, who would train him up on the application he would be supporting: a WebSphere-based Java application full of Enterprise Java Beans.Paramdeep reserved time with Rajiv in Outlook, arranging to meet at Rajiv's cubicle for half an hour. Rajiv accepted. At the agreed-upon time, Paramdeep walked over with a notebook and pencil in hand, intent on copying down all the pertinent information he would hear. When he reached Rajiv's desk, however, the elder developer waved Paramdeep away from his spare chair before he had a chance to sit down."Sorry, more urgent stuff came up," Rajiv said, turning back to his monitor. "The best way to learn about the application is to dive right in. I'll give you one of the simpler tasks. All you need to do is write a bean that'll call a Sybase stored procedure to get the next sequence ID of a domain table, then create the next object based on that ID."Paramdeep stood there wide-eyed and frozen, pencil hovering uselessly over paper. "What?""I've already built an EJB for the database connection layer and all the handling code," Rajiv continued, still intent on his screen. "There's also a stored procedure in the common schema for getting the ID. You just have to put them all together.""Uh—?""I'll send an email with the relevant class names," Rajiv cut him off."OK. I'll, uh, let you know if I have any trouble?"Rajiv was too caught up in his urgent business to respond.Paramdeep staggered back to his desk: scared, confused, and a bit dejected. But hey, maybe Rajiv was right. Once he dove into the code, he'd have a better understanding of what to do. He'd done JDBC before. It wasn't hard.Unfortunately, there was a stark difference between a computer science student's homework assignments and the inner workings of a creaky, enterprisey corporate behemoth. Try as he might, Paramdeep simply couldn't connect to the database schema Rajiv had told him about. He was connecting to a default schema instead, which lacked the stored procedure he needed. All of Paramdeep's attempts to solicit help from Rajiv—whether emailed, messaged, or sought in person—met with failure. His boss promised to get Rajiv talking, but that promise never materialized into Paramdeep and Rajiv spending quality time together.A strict deadline was looming. Desperate times called for desperate measures. Paramdeep emailed the database developer, Amita, suggesting his solution: creating a new stored procedure to call and return the value from the actual stored procedure, which would then return the value to his new bean.Minutes later, his phone rang. Caller ID showed it was Amita."You can't possibly want this!" she declared without preamble. "Just use the stored procedure in the schema.""I can't connect to it," Paramdeep explained."What do you mean, you can't?""I just can't!""Who's the tech lead on this project?""Rajiv.""Ohhh." A weary understanding permeated her tone, taking all the fight out of it. "OK, I get it. Fine, I'll make a synonym in the default schema."And that was why the ID generating procedure also existed in the default schema. Paramdeep couldn't help but wonder how many of the procedures in the default schema had gotten there this way. [Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.
Part of the pitch of Python is that it's a language which values simplicity and ease of use. Whether it lives up to that pitch is its own discussion, but the good news is that if you really want to create really complex code with loads of inheritance and nasty interrelationships, you can.Today's anonymous submitter started out by verifying some of the math in some extremely math-y analytical code. Previously, they'd had problems where the documentation and the code were subtly different, so it was important that they understood exactly what the code was doing.In one file, they found the core class they cared about:
As we all know, managing null values is its own challenge, especially when you're working in a functional style. So as languages like .NET add functional approaches like LINQ extension methods, they also add null coalescing operators and nullable types, making it easy to pass values around without getting surprised by an unexpected null.Unless you're whoever wrote the code that Abbie found, because they've managed to keep some surprises.
"In Poland, if you test positive for COVID-19, or come in contact with someone who has, you must stay home for a mandatory 10-day quarantine. During that time, you must use the government's mobile app named 'Home Quarantine' which tracks your location and requires you to send a selfie every couple of hours," wrote Jan K., "The app also reports if you are using a GPS spoofing app. For example, in this screenshot, it has detected a location spoofing app by the name of ...'Calendar'. Naturally, there are stiff penalties for violating rules of your quarantine like this. Also, as expected, there is no appealing the 'findings' of a buggy app like this."
A fair bit of "bad code" requires at least a passing understanding of the language in question, or the domain involved. But bad comments transcend programming languages. Vilx sends us this one, which comes from code which is definitely running in production.
Octavia (previously) didn't just inherit a C# application with dodgy approaches to string handling. It's also an application with questionable understandings of CSS.CSS is far from perfect, and offers a lot of pitfalls and traps. There's a reason the "impossibility" of vertically centering text is a punchline. It's so flexibly declarative that, in many cases, there are many ways to achieve the same styling result, and it's difficult to pick out the correct one. But one would hope that developers could at least avoid the obviously terrible ones.
Octavia inherited a decade old pile of C#, and the code quality was pretty much what one would expect from a decade old pile that hadn't seen any real refactoring: nothing but spaghetti. Worse, it also had an "inner platform" problem, as everything they put in their API could conceivably be called by their customers' own "customizations".One small block caught her eye, as suspicious:
Skill which you don’t use regularly can get rusty. It might not take too much to get the rust off, and remind yourself of what you’re supposed to be doing, but the process of remembering what you’re supposed to do can get a little… damaging.Lesli spent a big chunk of her career doing IT for an insurance company. They were a conservative company in a conservative industry, which meant they were still rolling out new mainframes in the early 2000s. “Big iron” was the future for insurance.Until it wasn’t, of course. Lesli was one of the “x86 kids”, part of the team that started with desktop support and migrated into running important services on commodity hardware.The “big iron” mainframe folks, led by Erwin, watched the process with bemusement. Erwin had joined the company back when they had installed their first S/370 mainframe, and had a low opinion of the direction the future was taking. Watching the “x86 kids” struggle with managing growing storage needs gave him a sense of vindication, as the mainframe never had that problem.The early x86 rollouts started in 2003, and just used internal disks. At first, only the mail server had anything as fancy as a SCSI RAID array. But as time wore on, the storage needs got harder to manage, and eventually the “x86 kids” rolled out a SAN.The company bought a second-hand disk array and an expensive support contract with the vendor. It was stuffed with 160GB disks, RAIDed together into about 3TB of storage- a generous amount for 2004. Gradually every service moved onto the SAN, starting with file servers and moving on to email and even experiments with virtualization.Erwin just watched, and occasionally commented about how they’d solved that problem “on big iron” a generation ago.Storage needs grew, and more disks got crammed into the array. More disks meant more chances for failures, and each time a disk died, the vendor needed to send out a support tech to replace it. That wasn’t so bad when it was once a quarter, but when disks needed to be replaced twice a month, the hassle of getting a tech on-site, through the multiple layers of security, and into the server room became a burden.“Hey,” Lesli’s boss suggested, circa late 2005. “Why don’t we just do it ourselves? They can just courier over the new drives, and we can swap and initialize the disk ourselves.”Everyone liked that idea. After a quick round of training and confirmation that it was safe, that became the process. The support contract was updated, and this became the process.Until 2009. The world had changed, and Erwin’s beloved “big iron” was declining in relevance. Many of his peers had retired, but he planned to stick it out for a few more years. As the company retired the last mainframe, they needed to reorganize IT, and that meant all the mainframe operators were now going to be server admins. Erwin was put in charge of the storage array.The good news was that everyone decided to be cautious. Management didn’t want to set Erwin up for failure. Erwin, who frequently wore both a belt and suspenders, didn’t want to take any risks. The support contract was being renegotiated, so the vendor wanted to make sure they looked good. Everyone was ready to make the transition successful.The first time a disk failed under Erwin’s stewardship, the vendor sent a technician. While Erwin would do all the steps required, the technician was there to train and supervise.It started well. “You’ll see a red light on the failed disk,” the technician said.Erwin pointed at a red light. “Like this?”“Yes, that exactly. Now you’ll need to replace that with the new one.”Erwin didn’t move. “And I do that how? Let’s go step-by-step.”The tech started to explain, but went too fast for Erwin’s tastes. Erwin stopped them, and forced them to slow it down. After each step, Erwin paused to confirm it was correct, and note down what, exactly, he had done.This turned a normally quick process into a bit of a marathon. The marathon got longer, as the technician hadn’t done this for a few years, and was a bit fuzzy on a few of the steps for this specific array, and had to correct themselves- and Erwin had to update his notes. After what felt like too much time, they closed in on the last few steps.“Okay,” the tech said, “so you pull up a web browser, go to the admin page. Now, login. Great, hit ‘re-initialize’.”Erwin followed the steps. “It’s warning me about possible data loss, and wants me to confirm by typing in the word ‘yes’?”“Yeah, sure, do that,” the tech said.Erwin did.The tech thought the work was done, but Erwin had more questions. Since the tech was here, Erwin was going to pick their brain. Which was good, because that meant the tech was still on site when every service failed. From the domain service to SharePoint, from the HR database to the actuarial modeling backend, everything which touched the SAN was dead.“What happened,” Erwin demanded of the tech.“I don’t know! Something else must have failed.”Erwin grabbed the tech, Lesli, and the other admins into a conference room. The tech was certain it couldn’t be related to what they had done, so Erwin escalated to the vendor’s phone support. He bulled through the first tier, pointing out they already had a tech onsite, and got to one of the higher-up support reps.Erwin pulled out his notes, and in detail, recounted every step he had performed. “Finally, I clicked re-initialize.”“Oh no!” the support rep said. “You don’t want to do that. You want to initialize the disk, not re-initialize. That re-inits the whole array. That’s why there’s a confirmation step, where you have to type ‘yes’.”“The on-site tech told me to do exactly that.”The on-site tech experience what must have been the most uncomfortable silence of their career.“Oh, well, I’m sorry to hear that,” the support rep said. “That deletes all the header information on the array. The data’s still technically on the disks, but there’s no way to get at it. You’ll need to finish formatting and then recover from backup. And ah… can you take me off speaker and put the on-site tech on the line?”Erwin handed the phone over to the tech, then rounded up the admins. They were going to have a long day ahead getting the disaster fixed. No one was in the room to hear what the support rep said to the tech. When it was over, the tech scrambled out of the office like the building was on fire, never to be heard from again.In their defense, however, it had been a few years since they’d done the process themselves. They were a bit rusty.Speaking of rusty, while Erwin continued to praise his “big iron” as being in every way superior to this newfangled nonsense, he stuck around for a few more years. In that time, he proved that he might never be the fastest admin, but he was the most diligent, cautious, and responsible. [Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.
Long-lived projects can have… interesting little corners. Choices made 13 years ago can stick around, either because they work well enough, or because, well, every change breaks somebody's workflow.Today's anonymous submitter was poking around the code base of a large, long-lived JavaScript framework. In a file, not modified since 2007, but still included in the product, they found this function.
Time just flies right past, and before you know it, the holidays will be here. Which is why you had better hurry up and try your hand at giving us the best WTF Christmas Story ever, to help us found a new holiday tradition. Or at least, give us one bright spot in the yawning abyss of 2020.Can you teach us the true meaning of WTFMas?What We WantWe want your best holiday story. Any holiday is valid, though given the time of year, we're expecting one of the many solstice-adjacent holidays. This story can be based on real experiences, or it can be entirely fictional, because what we really want is a new holiday tradition.The best submissions will:
Alleen started by digging into a PHP method which was just annoying. _find_shipment_by_object_id would, when it couldn't find the ID, return false, instead of the more expected null. Not terrible, but annoying. Worse, it didn't return the shipment eihter, just a key which could be used to fetch a shipment from an array.Again, all that's just annoying.It was when looking at the delete_shipment method that Alleen had the facepalm moment.
Cicely (previously) returned to the codebase which was providing annoyances last time.This time, the code is meant for constructing objects based on a URL pattern. Specifically, the URL might have a format like api/resource/{id}. Looking at one of the constructors, though, it didn’t want an ID, it wanted an array of them. Cicely wasn’t passing multiple IDs off the URL, and wasn’t clear, from the documentation, how it worked, how you supplied those IDs, or frankly, what they were used for. Digging into the C# code made it clear, but still raised some additional questions.
Marlyn’s employer ships software for a wide variety of CPU architectures. And depending on which branch of the product you were digging into, you might have code that builds for just i386, x86_64, PPC, and PPC64, while another branch might add s390, s390x, and aarch64.As you might imagine, they have a huge automated test suite, meant to ensure that changes don’t break functionality or compatibility. So it’s a pity that their tests were failing.The error messages implied that there were either missing or too many files, depending on the branch in question, but Marlyn could see that the correct build outputs were there, so nothing should be missing. It must be the test suite that had the error.Marlyn dug into the Python script which drove their tests, and found the get_num_archs function, which theoretically would detect how many architectures this branch should output. Unfortunately, its implementation was straight out of XKCD.
Russell F sends us this C# "fuction", and I have to be honest: I have no idea what it's supposed to do. I can trace through the logic, I can see what it does, but I don't understand why it does it.
As a personal perspective, I don't tend to believe that mastery of a programming tool is nearly as important as mastery of the codebase and problem domain you're working on. But there are some developers who just don't want to learn the codebase or what other developers are doing.Take Jessica's latest co-worker, which is similar to some previous co-workers. In this case, there was a project in flight that was starting to fall behind schedule. Management did what management does in this situation: they threw warm bodies at the project and ensured that it fell further behind.Brant was one of those warm bodies, and Brant did not want to learn what was already in the code base. He was going to do part of the JavaScript front end, he was going to rush to get it done, and he was going to copy-paste his way through.Which lead to this: