by Remy Porter on (#5N3SC)
I have a very casual interest in magic tricks. I certainly don't have the patience to actually learn to perform any well, but I enjoy watching them and piecing together how they're done. What really captures my interest is that actually performing a trick is about following a well-defined path, and by following that path you can achieve incredibly impressive effects. But if you just see the effect without understanding the path, and try and replicate it yourself, it's probably not going to work.In programming, there are certain things I consider "frickin' magic". They can create impressive effects, but the actual mechanism is concealed behind enough layers of abstraction that, if you don't stick to the carefully defined path, you can make some mistakes.Object-Relational Mappers and .NET's LINQ features leap to mind as peak examples of this. We have a lot of LINQ related WTFs on the site.Today's is a simple one, which highlights how, when one attempts to replicate the magic without understanding it, problems arise.
|
The Daily WTF
Link | http://thedailywtf.com/ |
Feed | http://syndication.thedailywtf.com/TheDailyWtf |
Updated | 2024-11-22 03:01 |
by Lyle Seaman on (#5N158)
Frequently we are sent submissions harking from that rainforest retailer,or the other one, or one of the smaller ones. It doesn't matter which,the wtferry is limited as these are almost always just some hacksupplier uploading bogus data. TRR only cares about speedy delivery,and TOO cares about being cheapest, while OOTSO are just trying to keep theirbricksnmortar shops alive. I don't usually run these, but this weekI've got a bunch of them saved up so I'm giving you six for the priceof NaN.
|
by Remy Porter on (#5MZX9)
Lets say you have a 64-bit integer. You want the first 42-bits. Now, if your language has a bitshift operator, you'd be tempted to do something like largeNumber >> 22.But what if your language also has all sorts of advanced stream processing and map functions? It'd be a shame to not use those. Tarah's shop uses Rust, and thus they do have all those exciting advanced stream processing. Her co-worker decided they just needed to be used:
|
by Remy Porter on (#5MYNR)
One of the big pieces of advice about using exceptions and errors is that they shouldn't be used for flow control. You catch an exception when an exceptional event happens, but you don't, for example, throw an exception to break out of a loop.Unless you're Python, which throws exceptions to break out of loops. That's just how iteration works. But we're not here to talk about Python.If a sufficiently motivated programmer can write LISP in any language, today's code, found by Maxi attempts to write Python in VB.Net. This snippet represents a general pattern around fetching data from temporary files.
|
by Remy Porter on (#5MX6C)
Alex sends us some Objective-C code which… well, let's just say that the code is suspicious looking, but there's nothing clearly bad about it.
|
by Remy Porter on (#5MVZK)
Some time ago, Will started a new job- a four month contract to take an old, ugly DOS application and turn it into a new, shiny VisualBasic 6 application. "And," the new boss explained, "the new program is almost done anyway. It's just that the last guy left, so we need someone to take it over the finish line."A key feature was that it needed to be able to fetch PDF files stored on a shared network drive. The order numbers were serialized, but the PDFs themselves were organized by year, creating file paths like I:\ORDLOG\2007\172.pdf. Now, in this particular block of code, one had access to both the ordnum and the ordyear, so constructing this path could be a trivial exercise. The previous developer did not take the trivial path, though.
|
by Lyle Seaman on (#5MS13)
|
by Remy Porter on (#5MQJA)
It's bad news when you inherit a legacy PHP CMS. It's worse news when you see that the vast majority of the files were last changed in 2002 (of course there's no source control).That is the unfortunate position that Elda found herself in.Like most CMSes, it needed to let users upload files. But we don't want to let users upload any arbitrary file, so we need to check that the file extension is correct. I mean, ideally, we want to check that the file is a valid file of the appropriate type so we don't serve up badfile.exe.mp3, but for an ancient PHP CMS just checking the extension is likely asking a lot. Especially when we see how this code performs that check.
|
by Remy Porter on (#5MP04)
Alexandar works with a veteran software architect. It's important to note here that a veteran is someone who has had experience. It certainly doesn't mean that they learned anything from that experience.This veteran was given a task to write a C# method to populate a user's news feed. The goal was to find the five most recent news articles and add them to the list. Now, this is a large scale CMS, so those articles need to be fetched from ElasticSearch.This was their solution:
|
by Remy Porter on (#5MMFK)
Years ago, Aleshia W started a job in a VB.Net shop. There's a lot I could say about those kinds of environments, but I'd really just be padding out the article, so let's just get right to the code- which pads out a Year string.
|
by Remy Porter on (#5MKFD)
Last week, we took a look at a hash array anti-pattern in JSON. This week, we get to see a Python version of that idea, with extra bonus quirks, from an anonymous submitter.In this specific case, the code needed to handle CSV files. The order of the columns absolutely matters, and thus the developer needed to make sure that they always handled columns in the correct order. This led to code like this:
|
by Lyle Seaman on (#5MGP9)
Music fan Erina leads off this week with a double contraction!"Who knew Tom Waits was such a gravelly-voiced Relational Databasepoet?" she Mused. "You'd've thought that SQL modes wasmore of an indy garage esthetic." You might've, Erina, but I wouldn't've.
|
by Remy Porter on (#5MFCX)
Validating email addresses according to the actual email specification is more complicated than you usually think. Most homebrew validation tends to just get something that's relatively close, because hitting all the rules requires some fancy regex work. And honestly, for most applications, "pretty close to correct" is probably fine. If you actually care about collecting valid email addresses, you'll need to actually send mail to the address and have the user confirm receipt to "prove" that the email address is real, valid, and actually accessible.Still, some "close enough" solutions are better than others. Jon found this C# code:
|
by Remy Porter on (#5ME90)
Validation highlights the evolution of a programmer as they gain experience. A novice programmer, when given a validation problem, will tend to treat the string like an array or use substrings and attempt to verify that the input is the correct format. A more experienced programmer is going to break out the regexes. A very experienced programmer is going to just find a library or built-in method that does it, because there are better ways to use your time.Andrea provides a rare example of a developer on the cusp between regexes and built-in methods.
|
by Remy Porter on (#5MCTK)
There's a lot of room for disagreement in technology, but there's one universal, unchangeable truth: Oracle is the worst. But a second truth is that there's nothing so bad a programmer can't make it worse.Someone at Ben's company needed to take data from a database and write it to a file. That file needed to have some specific formatting. So they used the best possible tool for the job: a PL/SQL stored procedure.Now, PL/SQL is a… special language. The procedural elements it adds to SQL have a distinctly "we want to sell this to mainframe programmers" vibe, which makes the syntax verbose and clumsy. It frequently creates situations where things which should be easy are incredibly hard, and things which should be hard are impossible. But it's technically a feature-rich language, and you can even write web servers in it, if you want. And if you want to do that, you either work for Oracle or you should go work for Oracle, but certainly shouldn't be allowed out to mix with the general public.In any case, Ben's predecessor decided to generate a carefully formatted text file in PL/SQL, and had… their own way of accomplishing things.
|
by Remy Porter on (#5MBPK)
When Arbuzo joined a new team, they helpfully provided him some sample code to show him how to interact with their JSON API. It was all pretty standard-looking stuff. If, for example, they fetched a Customer object, it would have some fields about the customer, and an array containing links to orders that customer had made. One of the samples helpfully showed iterating across the orders array:
|
by Lyle Seaman on (#5M908)
This week's opening Error'd submission required a bit of translation forthe monoglots among us, but it was worth the work. Not speaking even een beetje of Dutch, I was forced to use Google's own translationservice to see what it was that had so worried our friend Sebas. And it's a doozy.
|
by Remy Porter on (#5M7MJ)
Pete has had some terrible luck with the lead programmers he's worked with. He's had a few which are… well, they don't take feedback well. Like his current team lead, who absolutely doesn't let any of the other developers review or comment on his code. "Don't ask me questions, you should know this already," is a common refrain. Speaking of questions:
|
by Remy Porter on (#5M618)
Jan's company has an application which needs to handle an Excel spreadsheet, because as I'm fond of pointing out, users love spreadsheets.The JavaScript code which handles parsing the spreadsheet contains… some choices. These choices caused it to fail on any spreadsheet with more than twenty six columns, and it's not hard to see why.
|
by Remy Porter on (#5M4JG)
One of the arguments against comments in code is that they create a need to have two things updated: the code and the documentation have to be kept in sync. Inevitably, they'll drift apart.David works with a junior developer who came onto the team with strong opinions about, well, everything. One of those strong opinions is that every single line needs to have comments. Each and every one.This is the end result:
|
by Remy Porter on (#5M3GJ)
Folks who first learned to type on typewriters tend to prefer putting two spaces after a period. Most of the rest of us prefer just one. And this may have caused a performance problem.Rob's application had a quick search feature to track down customer claims. One day, the quick search was running quickly and efficiently. A user could type in a claim number, hit enter, and a moment later their screen would show the claim. Suddenly, it slowed down. It wasn't just the gradual decline of growing data or stale statistics or bad indexes. It was a code change, and it didn't take long to find the problem:
|
by Lyle Seaman on (#5M14Q)
In the wake of yet another extraordinary ransomware attack, most businessesare finally beginning to implement the sorts of security measures they knewall along they should put in place. "Someday soon, when we get the time."Some writers have been calling it "unprecedented" but you and I know just how precedented it really is.Loyal reader Aubrey leads off with an insider report,writing "Corporate IT recently migrated the entire companyto a new antivirus program, and it seems to have flagged*its own update* as likely malware." That's what we callfastidious.
|
by Remy Porter on (#5M00R)
One of the "legacy" PHP applications needed a few bugfixes. "Legacy" in this case, means "written by a developer who doesn't work here anymore", so mostly everyone tried to dodge getting those bugfixes assigned to them. Joe was taking a three day weekend at the time, so a helpful co-worker assigned the tickets to him.The code wasn't an absolute disaster, but it suffered from being written by a "smart" programmer. Since they were so smart, they couldn't just do things using the basic language constructs, they had to find clever ways to abuse them.For example, why would you write a for loop, with a counting variable, when you could do this instead?
|
by Remy Porter on (#5KYW4)
Arguably, the biggest problem with SQL as a query language is that we usually execute SQL statements from inside of some other programming language. It tempts us into finding quick hacks to generate dynamic SQL statements, and if we do it the quick way, we find ourselves doing a lot of string concatenation. That way lies SQL injection vulnerabilities.Constructing SQL statements by stringing together text is always a bad idea, even if you're still using query parameters. There's a reason why most modern database wrappers provide some sort of builder pattern to safely construct dynamic queries. Even so, everyone wants to find their own… special way to accomplish this.Take this sample from Sciros:
|
by Remy Porter on (#5KXSN)
The story of the week in software development is Github's Copilot, which promises to throw machine learning at autocomplete for a "smarter" experience.Notably, one of their examples highlights its ability to store currency values in a float. Or to generate nonsense. Or outputting GPLed code that was used in its training set.That last one raises all sorts of questions about copyright law, and the boundaries of what constitutes fair use and derivative works, and whether the GPL's virality can "infect" an ML model. These are questions I'm not qualified to answer, and that may not have a good answer at the moment. And certainly, the answer which applies to the US may not apply elsewhere.Besides, copyright law is boring. What's fun is that Copilot also spits up API keys, because it was trained on open source projects, and sometimes people mess up and commit their API keys into their source control repository. Oops.And even their examples don't really constitute "good" code. Like their daysBetweenDates, straight from their website:
|
by Mark Bowytz on (#5KWNH)
|
by Lyle Seaman on (#5KSV6)
Last week we lightly brushed on the novel conspiracy theory thatperhaps the HBO hullabaloo had been intentionally inspiredby their social media team, and suggested you might join them.Apparently the media managers at Subway had been hungering forpublicity as well.TDWTF sandwich specialist Carlos buttered us up, saying "I'm sure you've receiveda ton of these already [ed: we hadn't], but what's one more?"
|
by Remy Porter on (#5KRA3)
Good logging is an invaluable tool for debugging and diagnosing your applications. No logging makes that job harder, but not as hard as bad logging. Logging that doesn't log useful information, that doesn't help highlight the flow of the application, etc.Volker was trying to track down a bug that was only raising its head in production, but the log files were spammed with nothing more than "echo". Millions and millions of log lines that were just that. A quick CTRL+F through the code later, and the offending method was found:
|
by Remy Porter on (#5KPSJ)
C++ templates are, notoriously, a Turing complete language on their own. They're complicated, even when you're trying to do something simple. Related languages avoid that complexity, and favor generics. Generics are templates with all the sharp bits filed down, but still powerful enough to make datastructures that don't need to know the details of the data they're operating on.This article isn't about generics, though. It's about ORMs, specifically the .NET Entity Framework system. It's common to use the Repository Pattern to abstract out data access a bit. Coupled with the underlying DBSet class, which roughly represents a database table, you can easily create repository objects and related mocks for testing.Making your repository class generic is also a good idea. Basic CRUD operations don't really need to know the details the data they're operating on. You can create one repository instance for each type of data you need to store- each table- all based on the same generic type.But it's possible to make your repository too generic. Take Paulina's company. Here's a few key lines from their generic repository.
|
by Remy Porter on (#5KN9E)
Patsy's company has a product that's "number one" in their particular industry. It generates lots of revenue, but a lot of the code dates back to the far-off year of… 2017. Coding practices were… uh… different, four years ago? Especially in the rapidly maturing language of… Java?Within Patsy's company, they do refer to their 2017 code as "legacy" code, and it has left quite the legacy. For example, here's how they parse numbers:
|
by Remy Porter on (#5KKWW)
When we write code, we have certain assumptions. Most of these times, these assumptions are fine, and allow us to skip past some hard decisions. But sometimes, these can lead to problems. The infamous example would be the Y2K problem- the assumption that nobody'd be running this program in 40 years seemed reasonable at the time. We might assume that nobody'd type too fast. We might assume our sensor is accurate.Darren sends us some code that has a much milder assumption than those:
|
by Lyle Seaman on (#5KGWY)
The most eventful day in Error'dland narrowly missed our publication windowlast week. As everyone must surely know by now, somebody at HBO Max wastesting in production. And the Internet blew up.
|
by Ellis Morning on (#5KFD1)
|
by Alex Papadimoulis on (#5KDWQ)
|
by Remy Porter on (#5KC8S)
|
by Alex Papadimoulis on (#5KANQ)
|
by Lyle Seaman on (#5K7QF)
Greenville resident Terry K. discovers the weather is on the fritz today. "The chanceOfTemplateFailure seems high today," says he.
|
by Remy Porter on (#5K67G)
Mark's team needed someone to write a pretty straight-forward report for their Python application. It would take a set of keyword arguments, turn those into a filter, apply the filter, and get the results back.This was implemented in two methods. First:
|
by Remy Porter on (#5K4QF)
The time and effort needed to complete a project and the amount of time available rarely line up well. Wayne M's company found themselves in a position where what they needed to deliver and what they could deliver by the deadline simply didn't match up.The requirements were well specified, so they bundled up a bunch of requirements for search-related functionality, and handed them off to a self-described "world class" developer working on contract.When the developer handed off their C# code, well, there were some problems. Like the code didn't work. It didn't even compile. Even if it did compile, it was just… bad.
|
by Remy Porter on (#5K336)
Once upon a time, someone wanted to add a banner to a web page. They also wanted the banner to only appear after a certain date. Jack stumbled across their implementation when trying to understand why the banner would vanish for two weeks at the start of every month.
|
by Remy Porter on (#5K1NJ)
Behind every code WTF is a process WTF. For example, Charles W was recently tasked with updating some file-handling code to match changes in the underlying file-format it parses. This is the C code which parses an integer:
|
by Lyle Seaman on (#5JYC7)
It's been quite a few years since I was last in Silicon Valley.So it wouldn't surprise me at all if someenterprising restaurateur has unveiled a trendy pub and stolenallthe humorous thunder from Sean's submission. I'll be more surprisedif they haven't.Says Sean K."I love trying new beers, but these varieties remind me too much of work."418's all around! Alas, the keg of 204 has kicked.
|
by Remy Porter on (#5JWT6)
A few years back, Alvin was in college, and took his first formal summer job as a programmer. It was supposed to be just some HTML layout work, and the designer handed him a few sample pages. "Just do it like this."The "sample pages" were a mishmash of random indentation, huge swathes of commented out code, and all those other little traits of "someone's just coding in production, aren't they?" that crop up in files. Still, it was just some HTML layout work, so how hard could it be?Not too hard- until Alvin started popping up the DOM inspector. Every time he opened debugging windows in his browser, the page started misbehaving. Menus stopped staying popped open, or would pop open at seemingly random intervals. He could refresh, and it would go away, but the next time he opened (or closed) the DOM inspector, the problems would come back.In the one JavaScript file in the project, Alvin found this:
|
by Remy Porter on (#5JVDM)
Operator overloading is one of those "dangerous" features. Like multi-parent inheritance, it can potentially create some really expressive, easy to read code, or it can create a disaster of incomprehensible nonsense.In C++, many core classes use operator overloading, most notably the I/O classes, which reuse (or abuse) the bitshift operators into stream operators. So, for example, one possible way of converting a string into an integer might be to do something like this:
|
by Remy Porter on (#5JSQD)
Maximillion was hired to maintain a PHP CMS. His new employer, up to this point, had just been contracting out work, but as time went on, contracting rates got higher, the amount of time required to add basic features kept going up. It was time to go ta a full time employee."The system's pretty simple," the hiring manager explained during the interview, "as I understand it, it's basically just one PHP file."It was not just one PHP file, but the manager wasn't that far off. The front page of the site was 4.9MB. That's not 4.9MB rendered, that's the PHP file. PHP and HTML existed side by side with in-line JavaScript and in-line CSS.And the code had some… treats.
|
by Remy Porter on (#5JR9T)
Cornelius was working with some code where the objects might be "active" or "inactive". His code needed to do something different, depending on whether the objects were "active" or not, but fortunately, there was a handy-dandy IsActive method. Weirdly, that method required a bool parameter, but also returned a bool. Since there wasn't any useful documentation, Cornelius checked the C++ code.
|
by Lyle Seaman on (#5JN89)
Renault driver Oisin H. writes <<I had no idea French week had only six days>>It seems they too have never got the hang of Thursdays.
|
by Remy Porter on (#5JKQR)
Matt has plans for the next few years: dealing with the "inheritance" of some legacy systems.They're written in VB.Net, which isn't itself a problem, but the code quality leaves just a bit to be desired.
by Remy Porter on (#5JJ89)
Jesse had a "special" co-worker, Rupert. Rupert was the sort of person that thinks they're the smartest person walking the Earth today, and was quite happy to loudly proclaim that everyone else is wrong. Rupert was happy so long as everyone else was ready to bask in his "genius".Fortunately for Jesse, Rupert left, because he'd received a huge offer for a senior developer role at a different company. Everyone at Jesse's company privately chuckled about it, because this is the kind of code Rupert's genius produced:
by Remy Porter on (#5JGR9)
Virginia N (previously) needed to maintain some authentication logic. The actual rules for authentication weren't actually documented, so her choices were to either copy/paste some authentication code from a different project, or try and refactor the authentication method in this one.It was a hard choice. We'll dump the whole block of code, but I want to pull out a few highlights, starting with the opening condition: