by Remy Porter on (#5ZDE5)
"Don't concatenate long strings," is generally solid advice in most languages. Due to internal representations, strings are frequently immutable and of a fixed length, so a block like this:
|
The Daily WTF
Link | http://thedailywtf.com/ |
Feed | http://syndication.thedailywtf.com/TheDailyWtf |
Updated | 2024-11-21 20:01 |
by Remy Porter on (#5ZC3Z)
Martin's company had written a set of command line tools which their internal analysts could then string together via shell scripts to do their work. It was finicky and fragile, but frankly didn't work too badly for most cases.There was one tool, however, which seemed to be the source of an unfair number of problems. Eventually, Martin sat down with an analyst to see what was going wrong. The program would exit successfully, but wouldn't actually do any of the work it was supposed to. Instead of doing the normal thing and writing errors to STDERR, the tool wrote to a file. Which file, however, was determined by reading some shell variables, but the shell variables used by each of the tools were slightly different, because why would you build a consistent interface for your suite of analytical tools?Eventually, Martin was able to figure out where the errors were going, and saw that it was failing to connect to the backend database. That was a simple matter- just fix the connection string- but why was it exiting successfully when it couldn't connect?
|
by Remy Porter on (#5ZARA)
Let's say you saw a method called StrToGuid, in a C# codebase. Your first thought might be: "Wait, isn't there a built in parse? Well, I guess maybe they might do some sort of exception handling. But it still doesn't seem right." And then you'd take a look at the method signature and see that it takes both a string, and an integer named counter, and you'd think: "Wait, what?"Henrik H had a similar experience. His team hired a new developer, someone with 15+ years of experience. This is what they contributed to the codebase:
|
by Remy Porter on (#5Z9BM)
"There are a few more functions like this in the same file," writes Jenny, about today's submission. This is one which largely does speak for itself.
|
by Lyle Seaman on (#5Z6MQ)
This week's edition of Err'd gets off to a flyingstart with one that came in "over the transom" as t'were.Ordinarily, expired certs are a bit mundane for thiscolumn, but in this case, where this foiblefetched up is at least worth a chuckle.Jim M. wrote directly to the editor with this explanation."If you're looking for compliance reports to prove that your cloudprovider has solid security practices, be wary of this WTF with Azure.Quoting the site, SOC 2 Type 2 attestation report addressesthe requirements set forth in the Cloud Security Alliance (CSA)Cloud Controls Matrix (CCM), and the Cloud Computing ComplianceCriteria Catalogue (C5:2020) created by the German FederalOffice for Information Security (BSI).Sounds impressive!The link for Azure DevOps SOC 2 Type 2 attestation reportgoes to this link,https://docs.microsoft.com/en-us/compliance/regulatory/offering-soc-2,which shows that the cert for this page has expired. Try it here:https://servicetrust.microsoft.com/ViewPage/MSComplianceGuideV3"
|
by Remy Porter on (#5Z571)
Austin's team received a bug report. When their C# application tried to load certain settings, it would crash. Now, since this was a pretty severe issue in their production software, impacting a fair number of customers, everyone on the team dove in.It didn't take Austin long to spot the underlying problem, which isn't quite the WTF.
|
by Remy Porter on (#5Z3R2)
In the endless quest to get asynchronous operations right, we're constantly changing approaches. From callbacks, to promises, to awaits, to observables. Observables are pretty straight forward: we observe something, like a socket or a HTTP request, and when something happens, we trigger some callbacks. In a lightly pseudocode version, it might look something like:
|
by Remy Porter on (#5Z2B4)
Lacy's co-worker needed to collect groups of strings into "clusters"- literally arrays of arrays of strings. Of great importance was knowing how many groups were in each cluster.Making this more complicated, there was an array list of clusters. Obviously, there's a code smell just in this data organization- ArrayList<ArrayList<String[]>> is not a healthy sounding type name. There's probably a better way to express that.That said, the data structure is pretty easy to understand: I have an outer ArrayList. Each item in the ArrayList is another ArrayList (called a cluster), and each one of those contains an array of strings (called an answer, in their application domain).So, here's the question: for a set of clusters, what is the largest number of answers contained in any single cluster?There's an obvious solution to this- it's a pretty basic max problem. There's an obviously wrong solution. Guess which one Lacy found in the codebase?
|
by Remy Porter on (#5Z108)
Giles's company has a hard time with doing things in the database.In today's example, they attempt the very challenging task of generating unique IDs in a SQL Server database. Now, what you're about to see follows the basic pattern of "generate a random number and see if it's already been used", which is a fairly common anti-pattern, but it's managed to do this in some of the worst ways I've ever seen. And it can't even hide behind the defense of being written a long time ago- it's a handful of years old.Comments to this C# code have been added by Giles, and no, there were no comments.
|
by Remy Porter on (#5YX38)
Carolyn's company has a bunch of stringly-typed enums. That's already a problem, even in Python, but the other problem is that they need to display these in a human readable format. So, "ProductCategory" needs to become "Product Category". Now, it's true that every one of these stringly typed enums follows the PascalCase convention. It's also true that the list of them is constantly growing.So this is the method someone wrote for formatting:
|
by Remy Porter on (#5YVWD)
Steve's predecessor knows: sometimes, stuff happens that makes you go "WTF". While Steve was reviewing some inherited PHP code, he discovered that this predecessor had built some code to handle those situations.
|
by Remy Porter on (#5YTFA)
When companies reinvent their own accounting software, they usually start from the (reasonable) position of just mirroring basic accounting processes. You have transactions, for an amount, and then tagged with information about what the transaction actually represents. So, for example, if you wanted to find all the transactions which represent tax paid, you'd need to filter on some metadata and then sum up the amounts.It quickly gets more complicated. In some organizations, that complexity keeps growing, as it turns out that each department uses slightly different codes, the rules change over time, this central accounting database gradually eats older databases which had wildly different rules. Before long, you end up with a database so krufty that it's a miracle SQL Server doesn't just up and quit.That's the situation Giles W found himself in. What follows is an example query, which exists to answer the simple question: on 20th December, 2013, how much tax was paid across all transactions? For most database designs, that might be an expensive query, but hopefully a simple query. For this one… well… they may need to do some redesigning. Note the horizontal scrolling on today's code, there was no good place for me to add linebreaks for readability.
|
by Remy Porter on (#5YS6R)
Shery sends us perfectly innocent looking Java class, marked up with some annotations. The goal of this class is to have an object which contains a list of names that is definitely not null. Let's see how we did.
|
by Lyle Seaman on (#5YPEK)
Shocked sharerRob J. blurts "I feel like that voltage is a tad high."
|
by Remy Porter on (#5YN13)
If you're working in a research field, references matter- specifically, the citations made by your paper and the citations eventually made against yours. But when programming, references can be hard.
|
by Remy Porter on (#5YKP6)
It's not nothing to never write confusing English. And it doesn't never influence the code that we write. Don't fail to look at this anti-pattern from today's un-named submitter.
|
by Remy Porter on (#5YJ9R)
In addition to being a developer, Beatrix W manages a few small email servers, which means she sometimes needs to evaluate the kinds of messages arriving and their origins, especially when they're suspicious. One such suspicious message arrived, complete with a few malicious links, and some hints of possibly being the start of a spear-phishing attack.That was concerning, and as it turns out, the email came through a vendor who specializes in sending marketing emails- but the requested sort (or at least the sort where you got confused about which box to uncheck at checkout and accidentially signed yourself up for a newsletter). So Beatrix tracked down the contact form on the company website.She filled out the form with a description of the issue. The form had a handy-dandy "Attachments" field, and the instructions said, "Attach the suspicious email with its full email headers." So, she copy/pasted the suspicious email, headers included, into a text file, and attached the text file. She reviewed her work, confirmed that the attachment had uploaded successfully, and then pushed "Send". A copy of her submission arrived in her inbox, attachment and all, so she filed it away and forgot about it.Two weeks later, the vendor replied.
|
by Remy Porter on (#5YH13)
While JavaScript (and TypeScript) may have conquered the world, those languages have… unusual conventions relative to some lower level languages you might encounter. I recently was having a debate with a C-guru, who lamented all the abstractions and promised that well written C-code would forever be faster, more compact, and easier to read that the equivalent code in a higher level language.That may or may not be true (it's not), but I understand his point of view.Lily comes from a background where she's used to writing lower level code, mostly C or C++ style languages. So when she tried to adapt to typescript, the idea that everything was a reference was inconvenient. An example of a thing which flummoxed her:
|
by Lyle Seaman on (#5YEEB)
While we don't know the precise taxonomy of the fabled dilemma, this week's submissions include a few wild examples.Jon has captured a classic sample of the anticancelling cancel, reporting"While bulk-deleting files from an S3 bucket, Amazondangled a carrot in front of me only to cruelly whip itaway at the last moment."
|
by Jane Bailey on (#5YD29)
Sandra from Initrovent, previously featured here on the site, has finally left that job, finding herself at InitAg instead. InitAg is a small agricultural tech startup, a little rough around the edges for a data science company, but overall functional. With one notable exception: The customer portal.The customer portal is a mid-sized Symfony application, built up over the course of 5 years by an externally contracted one-man shop (let's call him Bjørn) who jealously guarded the source code up until the point he decided to drop InitAg as a client in late 2021. Upon informing them he was dropping them, he took a few weeks to clean up some of the code before giving it to InitAg. The Symfony part was mostly all right, with a few small WTFs but nothing too surprising. However, part of the portal's task was the slicing of large (>1GB) image files into smaller chunks for display in a browser, and a few other time-intensive tasks. Which brings us to today's topic: queuing.There's lots of ways to do queuing right. If you're working in the modern day, you're probably going to use RabbitMQ or another AMQP message broker. If it's 1995, probably the Linux system queue. But Bjørn was a fan of "keeping things simple". What mechanism did he choose for the queue? A collection of "task files" (with no defined structure) in a shared directory, and a bash script on an every-5-minutes cron job polling that directory for the next task, which would then trigger other bash scripts that actually performed the long-running operation. Some of these scripts were many hundreds of lines long, and without any form of documentation or comments to explain why they were shuffling files around or performing other operations.Of course, that's not all. It turns out that a large number of the scripts were unused (tasks that had been superseded or were no longer needed), but only Bjørn knew which ones were and weren't active.Bjørn's reasoning for all of this? "I like to keep things simple."It also didn't help that Bjørn had terrible git hygiene and seemingly didn't know about .gitignore, so the directory with all these scripts in it contained about 7,000 of these task files.Thankfully, this WTF has a happy ending: Sandra was eventually able to kill off the home-built queuing mechanism and the vast majority of the scripts, and replace the whole mess with a nice RabbitMQ consumer. Still, you gotta love the guys who like to "keep things simple" by avoiding proven, robust solutions in favor of homebrew nonsense. [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
|
by Remy Porter on (#5YBSB)
Initech sold some expensive devices which supported location tracking. Their customers wanted to track the location of these devices, with full history of all previous locations, down to five minute increments.When Eurydice F joined the team, she understood that it would be a lot of data to manage. She was an experienced DBA, and had all sorts of ideas about how you might partition the database to make that scale of data manageable, and the ways you would index it to make access and retrieval efficient.What she found instead was a table called DEVICELOGDAY. It had three fields. The first was a date- only a date, no time information, the second was an integer field simply called deviceId, and the third was a CLOB field called data.There was also a temporary table, a transaction-local table, simply called DEVICELOG. This had more reasonable fields- a timestamp, a device ID, a lat/lon pair.The secret of the dataflow existed in two stored procedures, PACKLOGDAY and UNPACKLOGDAY. A previous developer had seen "we need to store a row for every device, every five minutes" as an unbearable transaction burden. So instead, they decided to store one row per device, per day. That was DEVICELOGDAY. Every five minutes, a device would report its location and put that location in the DEVICELOG temporary table. Then PACKLOGDAY would be called, with the device ID as a parameter.PACKLOGDAY would take all rows in DEVICELOG with that device ID (which, as its a transaction-local temp table, would be the only rows in that table), and append them to the data column in DEVICELOGDAY for that device and that day, as a character-separated-values entry, e.g.:
|
by Ellis Morning on (#5YAGM)
In 1981, Mark was hired at a company that produced minicomputers widely used in retail establishments and small/medium businesses. On the first day, Roger gave him a tour of the plant and introduced him to his new coworkers. After shaking hands and parting ways with Walt, the Manufacturing QA manager, Roger beckoned Mark to lean in close with an impish smirk."See, with each system we sell, we send out a response card that the installing CE or customer is supposed to fill out, telling us about any problems with the installation," Roger said. "One time, a 'squawk card' came back from a customer with the comment, Two dead rats in power supply. You know what Walt sent back? Must be shipping damage. They were alive when they left here."Mark laughed, but then also wondered if maybe he was being pranked as the FNG. "Did that really happen? If so, how is he still working here?""It did happen. Follow me!"Roger led him to the hallway just outside the cafeteria, over to a lit trophy case. He pointed inside at a plaque with an image of the squawk card mounted on it, response and all."There were some people who were pissed off, but, Walt's worked here for ages and has a ton of friends at Corporate," Roger explained. "He was fine! And he's a legend around here to this day."To Mark, it seemed a good omen for the kind of company and culture he'd signed onto. As the years passed, he got to tell the story to several new hires himself.Through multiple corporate spinoffs, mergers, and acquisitions, the plaque in the trophy case endured. It was still there when Mark finally parted ways with the company in 2009, and we can only hope that this corporate legend still endures. [Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
|
by Jake Vinson on (#5Y9DP)
|
by Lyle Seaman on (#5Y719)
During this, America's national season of shared trauma, ourregular contributor Mr. Bargle shares a bit of levity whichmay lighten your mood ever so slightly.Argle Bargle explains"My girlfriend is Thai. She speaks English, but not on anadvanced level, so when we chat, I typically translate toThai. I learned long ago to reverse the translation tomake sure the translation says what I meant. My girlfriendtook a leave of absence from her research position to bean entrepreneur. April 13-15 is the holiday of Songkran:Thailand's New Year celebration. She said she would toobusy to chat with me until the 15th. I mentioned that the15th is America's tax day. As a precaution, I translatedit and then reversed. The attached image is clearly notan error, but it's a helluva WTF. On the left is LOL...tax day in the USA in Thai. On the right is.... OMG."
|
by Remy Porter on (#5Y5TG)
SQL injection attacks are, in most environments, easy to avoid. Pass user input through parameterized commands and never do any string munging to build your SQL queries. And yet, we constantly see places where people fail to do this correctly.Eric's co-worker is one of "those" people. They were aware of what SQL injection was, and why it was a risk, but instead of using PHP's built-in functionality for avoiding it, they reinvented the wheel- now in a triangular shape!
|
by Remy Porter on (#5Y4H9)
Today is a short hit, as there's a comment I want to highlight. This comes to us from Benjamin Urquhart. It's his comment, it's his code, and it's his confession.
|
by Remy Porter on (#5Y39B)
Conditionals are a constant source of problems for some developers. Russell F inherited some code which needed to take a list of parts and filter the list of parts down to something which customers could actually order.The specific rule was that they needed to include only parts that were: not in stock and not in close out, in stock and not in close out, or in close out but also available. Which, given that business rule, that's exactly what the developer implemented:
|
by Remy Porter on (#5Y1ZA)
So much bad date-handling code is based in people reinventing methods that already exist, badly. That's code that solves a problem people have, that's already solved. But the really special code solves a problem nobody understands or wants solved.Take this C# function from Luke's co-worker.
|
by Lyle Seaman on (#5XZ7G)
It's astounding...The madness took its toll onChris N. who highlighted Monday "Your Microsoft Teams is out of date! This is after pressing Calendar."
|
by Remy Porter on (#5XXX8)
When we share code comments, it's usually because they demonstrate some lack of awareness or some carelessness about what's going on. A comment warning "I know I shouldn't do this" or a comment that contradicts the code in a funny way, that's usually what we share.But today's submission, from Dewey, is a bit different. Dewey wrote the comment, and it was in preparation for some serious refactoring. So this comment is the product of someone spending time to accurately analyze and understand a method, documenting its behavior, and explaining it so the code could be changed to something better. The WTF here isn't the comment, but the code it describes.
|
by Remy Porter on (#5XWM6)
Let's say you've got an older PHP application. Once upon a time, it was wired together by a pile of includes with no real organization or planning behind the organization. A developer went through and cleaned up the file organization.That's a happy ending, isn't it? No, it isn't, not for Scott. Because the developer doing the cleanup didn't want to risk breaking any files, and thus didn't actually do any final cleanup. Instead, in the labirynth of a thousand include files, many of them are dead ends containing only:
|
by Remy Porter on (#5XVDG)
Initech's latest offering, IniPrints, was a secure automation system for document management. The target audience was the banking industry, which meant that the system was sold as having robust and fine-grained role-based access control systems. As far as any one could tell, that was exactly what Initech was shipping, which meant IniPrints gained a reputation within IniTech as being a "good product", with "low maintenance".When Alan was assigned support on IniPrints, he expected it to be pretty quiet. So he was surprised when three of the veterans of the project, Carole, Larry, and Arthur desceded on his cube with grim tidings."We've got some concerns about IniPrints. You should probably take a deeper look at the code."With that ominious warning, the Fates- Carole, Larry and Arthur- vanished back into the cube farm. The trio had migrated from development to technical sales support roles, which meant they mostly interacted with customers anymore. They were not to be any help to Alan when it came to understanding the software.Unfortunately, neither was the documentation. There was none in the code, none in the commit history, and the code itself was incomprehensible. There was one Word document which was meant to be "the documentation", but it was less clear than the code. When Alan complained about the lack of documentation, his request eventually got back to the Fates, who replied: "check the big red filing cabinet for a hard copy of the documentation".Alan found the hard copy: it was the same incoherent Word document, printed out, and decorated with a series of coffee stains which did nothing to make the meaning more clear.Alan did his best to understand the software anyway. When it came to roles, it shipped with two roles: User and Manager. These two roles were used in the sales demo, and 99% of their customers never dove deeper into the security model than that. Those two roles worked perfectly and had well understood behaviors.Unfortunately, the Fates- Carole, Larry and Arthur- had just landed a contract with a new bank. And this bank was in the 1%- they needed a role-based access control system with much more advanced functionality. That's what IniPrints claimed to have, but the reality was different.The bank sent them a pile of security issues. Alan was the one person doing support, which meant Alan needed to triage and prioritize. He grouped the issues into four categories:
|
by Remy Porter on (#5XTGR)
Source control history can go a long way to telling a story. Take Cassi, who needed to run some PHP software which depended on a few binaries and shell calls to do its job. We can see the initial attempt to locate the path of a binary:
|
by Lyle Seaman on (#5XR0H)
Aspirational Caleb Su thinks this birth-year chooser is a WTF. "You have to be in at least 8th grade to join, meaning at the verylatest you could be born in 2009." Not so, Caleb, not so! A precocious8th grader might have been born as late as 2013. It could happen.
|
by Remy Porter on (#5XPP8)
One of the easiest ways to create a bug for yourself is to drop an empty catch into your application.Today's rather short CodeSOD comes from Dex, and was found in a payment process. This is code that handles actual financial transactions, which is why the comment attached to a common mistake is relevant here:
|
by Remy Porter on (#5XNCZ)
Ilsa's organization uses Terraform to handle provisioning their infrastructure. This mostly works fine for the organization, but one day it started deleting their load balancer off of AWS for no good reason.Ilsa investigated, but wasn't exactly sure about why that was happening. What she did find, however, was this particular ternary expression.
|
by Remy Porter on (#5XJVC)
There are some coding practices which likely arise from a good intent, but sometimes feel misplaced. For example, the "only one return from a function" tends to make code more complex and harder to read, instead of easier, ever if it theoretically makes debugging easier. I can at least understand the intent and reasoning behind it, even if I don't like it.Danny D's former co-worker had their own little rules. Specifically, sometimes when you write an if statement, you definitely need an else. Other times, you don't. That's confusing, because you have to make a choice. Instead of making a choice, just always use an else. Always.
|
by Lyle Seaman on (#5XGA3)
I saw my doctor this week and he told me I needed to go on a new diet. So here you go: all natural, no snark added.OverachieverBill T. reflected on his life achievements:
|
by Remy Porter on (#5XEZR)
We've had a bit of a run of PHP in the inbox lately, which is fine, but certainly isn't doing anything to help PHP's reputation as a WTF factory. This one comes from Lucio C, who was hired to fix a hacked WordPress installation.Much of the fixing was figuring out what data was safe to recover, what files may have been tampered with, and generally assessing the damage.While doing that assessment, Lucio found this perfectly legitimate file in a perfectly legitimate WordPress plugin. This file was not altered by the hackers, but…
|
by Remy Porter on (#5XDMP)
Nora found a curious little C# helper method. It was called in exactly one place and it is… not exactly necessary in any case.
|
by Remy Porter on (#5XCA9)
"So," Burt said, "our bonuses at the end of the year are based on our systems uptime?""Well," the middle manager introducing their new incentive program said, "not exactly. It's part of your team's performance targets, so we calcula-""Yeah, I get it," Burt said. "But your top tier goes up to 99.999% What about those of us who get 100% up-time?""Well, 100% is unreasonable to expect and-""Our phone system can. I set up the PBX myself. It's not going down. It's the most reliable system in the company. You should give a higher bonus to teams that can hit 100% uptime.""Ah…" The manager paused, nodded, and said, "I'll look into it," in the tone that made it quite clear that nothing was getting looked into but the conversation needed to move on.This was circa 2002, and Natalie had just joined Initech's operations team. Mostly, she was doing the unglamorous work of untangling the rats nets of Ethernet cables left by the last person in her position, discovering that spreadsheet containing server rack assignments was incorrect, and swapping in the new UPS system for the server room.The door next to the server room had two large buttons next to it. One of them was an accessibility button which would trigger the automatic door opener. This was useful for Natalie, when she had a cart-load of lead-acid batteries to replace. The second was the emergency stop button, which would cut power to everything in the server room.Now, everyone was quite aware that two similar buttons right next to each other but with wildly different functions was a problem. But upper management didn't want to spend money to alter the layout or replace the buttons with something to make them more visually distinct. But they needed to do something.So Burt, ever the problem solver, solved it. He cut a hole in the bottom of an old 5 1/4" floppy disk storage container, attached it to the wall over the emergency button, and demonstrated two features. First, by lifting the lid, you could easily and trivially access the emergency stop button. Second, it was just held in place with the weakest of drywall anchors and could easily be ripped from the wall in a real emergency. Someone decided that this was safe enough, and that "mitigated" the risk of an accidental shutdown.Near the time for yearly reviews, both Natalie and Burt happened to be doing some maintenance at a secondary site. Simultaneously, their phones rang: someone had pushed the big red button and shutdown the server room. They rushed back to address the problems that this caused, though something about the call stuck in Natalie's brain.Reviewing the security footage, later, the culprit was the "better idiot" who foils any idiot proof system: someone carrying a cart full of print outs walked right past the door-opener and spent several moments fiddling with the floppy disk case to figure out how to lift the lid and press the button inside.No one was concerned with the security footage when Burt and Natalie arrived. The server room was controlled chaos, as everyone was scrambling to manually reboot servers, resolve issues with machines not coming back up, and generally panicking-not-panicking because nobody had ever really tested a full recovery and no one was sure if their procedures worked.And that's when Natalie realized what struck her as odd about the phone call. It had come from one of the company numbers. One of the ones that ran through their PBX. The PBX was in the server room, it theoretically should have gone down when the emergency stop happened, but no- it had never rebooted, it had just hummed along quietly while everything else crashed.Natalie turned to Burt. "Wait, how is the PBX still up?""Oh, see that rack over there? It's got a rectifier and a bank of deep-cycle marine batteries. When the main UPS cuts out, our phone system has a backup power supply."In the yearly review, Burt's PBX system got a perfect 100% uptime rating. Burt's performance was not given equally high marks, though. Creating a fire hazard in the form of your own private battery bank and homebrew UPS, and not integrating with any of the key safety systems in the server room doesn't endear you to management.In the end, Burt got a scolding and a negative note in his employee file. His PBX got put on the main power supply, sharing the same main and backup power as everything else in the building. The next time someone accidentally pushed the big red button, Burt's phone system didn't maintain its improbable 100% uptime. [Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
|
by Remy Porter on (#5XB19)
Checking browser compatibility is less of a thing these days than it once was. In an ideal world, we check for the specific features we want to use, and fallback to a different approach, or fail gracefully if they don't exist. We use shims and polyfills and pile on all sorts of logic to navigate this mess.What we hopefully don't do is use user-agent sniffing. The user-agent string is, honestly, one of the kludgiest, messiest, and just generally offensive ways to divine browser behavior. It was, however, once the standard, and thus there is still plenty of code, usually older code, which does use user-agent sniffing.Which brings us to this code, from Megan. It comes from the admin application for a major logistics company for a European nation. This logistics company handles 90% of deliveries for books within that nation's borders, and is notorious for its buggy software, its habit of just dropping orders with no explanation, and generally being an unstable mess where you may have to try six times before your order goes through.
|
by Lyle Seaman on (#5X8AX)
Due to a chance astrological alignment, two famously alcoholicholidays collided Thursday. Your editor, along with scores of ecumenicists, atheists, heretics and other drunkards, took theopportunity to get plotzed, plastered, schnockered or fershnikitin every tradition possible. This poor column is the proof.Ruleoneian Colin has an interest in travel to far-off places, musing "I wonder what the currency in Rule-6 is."
|
by Remy Porter on (#5X6ZW)
We've discussed extension methods in .NET in the past. If you write a method with a signature like public static void foo(this string input), then you can invoke this method like myString.foo(). It acts like an instance method to a caller, but it really just invokes foo(myString). It's a nice way to inject functionality into existing classes, and many .NET libraries use this feature.Esromhaz's co-worker found an… application of this.
|
by Remy Porter on (#5X5KA)
Visual Basic .NET is actually not a terrible language. I don't think it'd ever be anyone's favorite language, and these days it's basically deceased, but it's essentially C# with verbose syntax. Even the APIs are identical…… almost.Because, you see, when Microsoft released VB .NET, their core plan was that it should be "easy" to port your existing VB6 code into VB .NET. This meant recreating a lot of static functions in the global namespace, like Mid (substring), or Kill (file delete). There were better, cleaner ways to do all of those things. For example, Kill throws an exception if you try and delete a file that doesn't exist, while File.Delete doesn't (but provides a status code).So while you should use the newer APIs, you could still do things the old fashioned way. It was like GoTo- you shouldn't use it, but you could.Russell F inherited some code which has all of these fun tricks.
|
by Ellis Morning on (#5X49T)
At the age of 17, our friend Argle had a job as a programmer for an aerospace firm, mostly working with commercial flight-deck equipment. Like with anyone new to a given industry, he found himself puzzling over the plethora of acronyms that got thrown around in conversation without a thought. Lacking an Internet to go look these things up in, Argle was forced to ask people to stop, go back, and explain. But what 17 year-old feels comfortable interrupting much older adults like that? Most of the time, the acronyms were scribbled down on a yellow legal pad, to be figured out later.The programming side of the job was no problem, at least. There was one case of something a little odd: someone handed him some coefficients of a polynomial and told him to make them into a FORTRAN function. He had no familiarity with curve fitting, but that part of the work had already been done for him. He implemented the function and moved on to other things. Some weeks later, he was working at his cube when a stern voice behind him caught his attention. "Mr. Argle."It was that tone of voice specifically reserved for calling someone to the carpet, and it made his viscera plummet. Swiveling around in his chair, he beheld a dozen people or more crammed all along the perimeter of his cube and spilling into its cramped confines. Some were in fancy business suits, some in full military regalia. All were wearing the most furious expressions he'd ever seen.Argle must've started an inch out of his chair."Mr. Argle." The military man closest to him spoke again, this time with the full weight of his glare bearing down on him. "We have jets that won't fly because of you.""Me?" Argle sputtered. "But—""That FORTRAN polynomial function we assigned to you!" another voice piped up. "That has to be it! You either made a mistake because you were careless, incompetent, or for some worse reason.""That?!" Argle's brain raced faster than it had ever raced before. "No! Here!" He swiveled to face his desk and sifted through a pile of folders sitting there. He'd been good about documenting all his work thus far, detailing the whats, whys, and hows. It took him a minute, as his hands shook and his panicked brain had trouble processing the words he looked at, but he was able to find his notes, along with the original coefficients that had been handed to him. He all but heaved the assembled evidence toward his prosecutors. "Here! This is all I did, I swear!"The tight crowd of higher-ups crowded even tighter around the papers, muttering inaudibly to one another and occasionally coughing. Their collective wrath dissipated, leaving behind an awkward gap of silence. At last, someone said a simple "Thanks" and handed the papers back to Argle. They marched off together, presumably to do this all over again to another poor soul who lacked adequate shielding.Argle heaved a sigh of relief. That day, he learned that the most important business-related acronym is and always shall be CYA. [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
|
by Remy Porter on (#5X2YX)
Initech had a lovely little Content Management System built by a third party that was good at "building" CMSes. That is to say, this company knew its way around a WordPress template.When Initech needed a new public-facing website, they went straight back to that vendor. Now, this new website was a complicated statistical tool, with all sorts of complicated business rules and requiring a large amount of custom programming. So the vendor that just cranked out WordPress templates may not have been a good fit for the project, but that didn't stop anybody.That's how Magnus M found code which looks like this:
|
by Lyle Seaman on (#5X095)
This week we're throwing a bone to all the antipunsters in the audienceand declaring a unilateral cease-fire on all alliteration, wordplay,jabs, jokes, or other japery. Starting now.Allie shares a redundancy that I think we've seenhere before, saying"It may be _technically_ right, but I don't have to like it."
|
by Remy Porter on (#5WYYK)
Cat has some Java code which handles text layout. Now, someone writing the code didn't understand the idea of enumerated types, so every constant is a string.That's a nuisance, but not a terrible problem. Of course, with Java's String handling, you also run into the fact that == will frequently work, because Java tries to reuse String instances, but it won't always work, and thus equals exists.So this code didn't actually work:
|