• P (unregistered)

    Plot twist: this StringManager is their product. They sell it to gullible companies back in the 90s.

  • P (unregistered)

    Also, how probable is it that this senior technical lead has coded Visual Basic for their whole life and it got into their brain?

  • pudin9 (unregistered)

    I'm almost tempted to try how many lines this would shrink into by using built-ins.

  • Little Bobby Tables (unregistered)

    This is where you cosy up to the senior dev manager's boss and perhaps his boss as well, take them out for golf or something, and once you're on best-buddy terms, start to discuss with them the benefits of keeping their senior staff on their toes by various techniques of training courses, code assessment, and the pillory.

  • purrification (unregistered)

    How else do you ensure your customers only use the best hardware available?

  • 3stdev (unregistered)

    I'm guessing that this code was written by someone who cut their coding teeth in COBOL and later learned C#. The idea of looping through a string and examining each character is pretty much the only way to handle these requirements in COBOL. I'll bet that mindset was the driving force to his approach. If my supposition is true, I'll also bet that the code processes in a linear fashion and doesn't take advantage of the Object Oriented architecture, since COBOL didn't have that, either.

  • Peter Tramo (unregistered)
    switch(boolFromLeft)
    {
    				case true:
    					...
    					break;
    				case false:
    					...
    					break;
    }
    

    If only there was a shorthand for this...

  • Junkfoodjunkie (unregistered)

    Holy fucknugget. What is wrong with people who code like this? What language were they taught in, to make this a reasonable way to do... Well, anything?

  • Quantum (unregistered)

    Hi, Remi! I struggle to understand one sentense in the Virtually Careful article, could you re-phrase / explain it to non-native speaker? How do you imagine gun + anything "at the same time"?

  • ray10k (unregistered) in reply to Quantum

    Re-reading the article, I understand the phrase "multiple-inheritance is one of those luxury foot-guns which allows you to blow off your own foot using anything that implements the shoot() method at the same time" as "Since multiple-inheritance lets you define an object to be specialized versions of multiple virtual objects, you could get unexpected behavior due to multiple base-classes defining a function with the same signature, meaning (per example) a photo camera-object 'shoots' as if it is a gun-object instead."

  • Anon (unregistered)

    I have worked on, and continue to work on, legacy code bases not that dissimilar to this.

    Fortunately the original coders and guilty parties are long gone, and while I don't like changing code just for the sake of it (even horrendous code), whenever I have had to make changes in the area anyway I have been able to rip up large chunks of rubbish and replace it with small simpler built-in methods.

    Can actually be quite satisfying!

  • WTFGuy (unregistered)

    I'm betting this StringManager class was originally written in something like TurboPascal or maybe DBASE or even Excel. Back when OO was bleeding edge stuff (or still 5 years in the future), and languages / APIs for string-ish datatypes had the moral equivalent of indexOf(), subString(), and that's about it.

    The problem is Mr. SeniorDev has been carefully curating this pile and porting it to each new language he encounters. Meantime it's grown some overlapping features. So today he thinks of the abstract any-language datatype of "strings" entirely through his data model of his 30 year old StringManager class. I'm willing to be he can't even tell you what most of the methods of the .Net String, StringBuilder, IFormat*, or Convert classes/interfaces/namespaces are, much less what they do.

    At every point in the life of a long-lasting project / product you have to ask yourself if today is the day to break with past practice and start using the latest new features of your language. C# is up to v7.0 now. I still maintain code originally written to C# v2.0 when v2.0 was the bleeding edge .Net version. Is today the day I drop a v7.0 syntax goodie or shiny new type in the middle of an old method? Or do I, in the name of consistency, keep doing 2.0 style work?

    It's surprisingly easy to fall into the trap that the right time to update is "never". Doubly so on a large codebase where the inner platform effect begins to take over. Add in heavy deadline pressure, a buggy product with no unit tests, and "not today" becomes the only answer defendable to a manager looking at the calendar.

    For darn sure there are plenty of poor coding decisions within many StringManager function. But that's a different meta-level of WTF from how he & his department ended up using TurboPascal (or whatever) in 2019.

  • David Davidson (unregistered)

    I tried searching random lines on github and google to try to find any leads, no dice

  • Craig Wagner (unregistered)

    I'm starting to think that you should be naming the companies, and possibly people, who wrote this kind of stuff. Think of it as a PSA for your readers so we know which employers to avoid.

  • (nodebb)

    NIH syndrome?

    I once interviewed with a small software company where the 'architect' felt that the C++ STL was too difficult to understand, so he wrote their own and everybody was expected to use that instead of the STL.

    Hard pass.

  • (>'-')> (unregistered)

    pudin9 (unregistered) 2019-08-21 Reply I'm almost tempted to try how many lines this would shrink into by using built-ins.

    WTF? The entire file could be replaced by one or two regexen and the built-ins themselves.

  • (nodebb)

    O...... What the actual.....?

  • (nodebb)

    There is room for disimprovement yet.

    A true non-believer would not trust using .IndexOf() or .Substring() either but implement his own method iterating the character array that a string is.

    When you don't do OO, do it thoroughly.

  • EwgB (unregistered)

    You know, sometimes (like for instance today), when I look for three days in search of some trivial-ish bug in our old-school three tier monolith made of several millions lines of Java code, some of them written before I wrote my first line of code, stumbling through 5000 line long classes with undocumented and/or unused methods, I think - maybe I should not have taken this job, maybe it is horrible. And then I read articles like this and realize that my job isn't that bad.

  • Argle (unregistered)

    [buries head in arms and weeps]

    I think I worked with him. I'm 57 now. 30 years ago, a cow-orker came to me with 2 pages of C code. "I have a bug in this." I asked "what does this do?" He began describing the variable declarations at the start. I cut him off. "No. In 20 words or less: what is this supposed to?" He stood there for a good minute looking like a deer in the headlights. Finally he said, "it takes a date string and converts it to three integers, month, day and year." I said, "great. and are the inputs already sanitized? That is, already guaranteed to be 2 digits each?" After confirmation I scribbled a single sscanf in the corner of the listing and told him to use that."That works?" Me: "that works." An hour later he says "that worked."

    I think he's still around somewhere. It's gotta be him in this story.

  • (nodebb)

    Imagine their RandomManager class.

  • ooOOooGa (unregistered)

    When I was in college, we had to do things ourselves - for the learning experience. It actually makes sense.

    When building a web page in javascript, you can only use javascript - not jQuery.

    When learning data structures and implementing a linked list, you have to actually implement the linked list yourself - no using the STL.

    For the process of learning how to do logical thinking and programming, it is great. But it does mean that after I graduated, I had to unlearn the habit of implementing everything myself with nothing but the core language features.

    It feels like this senior technical lead never unlearned that lesson.

  • Brian (unregistered) in reply to pudin9

    I'm gonna say... about 8?

  • zorkon ii (unregistered)

    Shouldn't someone copyright or patent this and refuse to license it to protect everyone?

  • ooOOooGa (unregistered)

    Using the fully qualified namespace calls isn't completely unnecessary. Doing it that way means that when you copy and paste one of these functions into a different scope (so that you can make a slightly modified version for that particular case), then you don't run into problems with having to remember to add include or import statements. You get fewer compiler errors at that point.

    [/sarcasm]

  • I dunno LOL ¯\(°_o)/¯ (unregistered)

    At first, due to the indentation, I thought inputMM and inputDD were enums to be used with this dog's breakfast of functions. It's actually the opposite. Instead of using sensibly named constants for common mode selection parameters, each parameter gets expanded to its own line of code with a comment of what that particular magic number (or magic string or magic bool) means. Depending on how he felt about indentation, this causes the average function call to expand to seven lines, none of which tells what the intent is of calling that particular string-mangling function. (as in Argle's "20 words or less".)

    And then I looked at the length of the article. Holy crap, but that's what you get when you expand simple function calls into 7-line monsters.

    Also, not supporting "+" in an e-mail address? Definitely he should have been taken out back and shot. Thank goodness for "contract-to-hire" giving you a chance to see the skeleton code in the closet first.

  • (nodebb) in reply to Quantum

    Hi, Remi! I struggle to understand one sentense in the Virtually Careful article, could you re-phrase / explain it to non-native speaker? How do you imagine gun + anything "at the same time"?

    (Hopefully I have this right as the original doesn't seem to be there anymore, I'm going on the other reply you got.)

    English has an expression "shooting yourself in the foot", meaning that what you were trying to do ended up simply hurting you (usually not in a physical sense, though.)

    Programmers have adapted that and sometimes refer to features that are likely to produce unexpected and undesirable results as foot-guns, basically saying they are things for shooting yourself in the foot. We are not talking about actual firearms when we say "foot-gun", although I have encountered the term used to describe things other than code.

  • Eric Gregory (github)

    Somehow I just know there aren't any unit tests for this.

  • (nodebb) in reply to P

    Rather than VB, this looks like a C guy (where you had to write everything like whitespace trimming yourself) had My Library, then learned Java (where everything is excruciatingly verbose), so he ported it to Java, then he ended up doing C# and of course he needs My Library.

    C# has simple fast built-ins to do nearly all this, but how can you trust the guys who wrote those?!?

  • Temporarily banned from Stackoverflow (unregistered) in reply to Oldtaku

    Java has a vast standard library (even better than C#, where it seems you need to monkey patch everything), there would have never been a reason to write this kind of code in Java either.

  • Little Bobby Tables (unregistered) in reply to Argle

    I found a bubble sort in a Java method in one of our business classes once. No, it was worse than that: there were two bubble sorts in that method (one copypasted and tweaked from the other) -- which one was used depended on whether you wanted to sort on A or B (actually it may even have been whether you needed to sort ascending or descending).

    I can't remember whether I rewrote it properly or whether I left it around to use as a bad example for colleagues to laugh at.

  • Little Bobby Tables (unregistered) in reply to Loren Pechtel

    In Soviet Russia, your foot shoots you!

  • Little Bobby Tables (unregistered) in reply to Argle

    "So what do you need to convert a date to three integers: day, month and year for?"

    "So I can work out what the next day is. See, I add one to the day, then work out whether that's greater than the number of days in the month (which I do in a separate function, I'm still working on the leap-year bit) and then if it is, I set it back to one and then I increment the month, and then I see whether that's greater than 12, and if it is, I set it back to 1 and then add 1 to the year. I've got another function to decrement."

    "Okay, and so what if you want to add more than 1 to the date?"

    "I just call my increment function that many times. Du-uh."

  • Dean (unregistered) in reply to WTFGuy

    I'm the guy who submitted this post. This may be the most plausible explanation for this. Mainframe code is also written here, so the dev may have come from the mainframe side. That said, I mean come on... Ten seconds with the language reference. Please.

  • Dean (unregistered) in reply to Eric Gregory

    Can confirm.

  • Deon (unregistered)

    Oops. My "name" is Deon, not Dean.

  • Deon (unregistered) in reply to Temporarily banned from Stackoverflow

    Is this true? I haven't touched Java since college, but I've not run into anything basic yet that .NET can't handle out of the box. I know Java added pipelines that work similarly to LINQ, but that's about all I know about the differences in the supporting libraries.

  • Deon (unregistered) in reply to I dunno LOL ¯\(°_o)/¯

    This is the worst code base that I have ever seen in my entire career. I just don't have words. I'm interviewing now.

  • BernieTheBernie (unregistered)

    Thanks for sharing your wonderful code, bro! I will integrate it into our code base, and I am sure it will enhance the performance magically.

  • Bart (unregistered) in reply to WTFGuy

    Even in TurboPascal it would not require 1800+ lines ...

  • medievalist (unregistered)

    This code would be great for testing or training an optimizing compiler.

  • isthisunique (unregistered)

    I've seen this kind of thing quite a lot. While it's good to have string functions, they need to be well written, clean, not add weird things and generally speaking be actually attached to the thing involving strings where possible so you don't end up with a God class.

    My peaves...

    1. Magic "workers everywhere with everything". In an application your should normalise everything on input and output but what some people do is just have a magic from string they use always, on every internal call needing it. You could only ever pass one format but will have to use a method that'll check for ten other things. Expect quirks, side effects and hidden errors. You see this already with is empty, if it's null or empty with whitespace. Heck, why not strip 0 and \0? What about unicode WS? I've seen pretty bad magic like this before. I was just looking at a lib that maps tld to country. For some reason it'll take a domain or an email address. Why not just a tld? Otherwise why not take any URI scheme or anything and try to identify the format and extract the domain?
    2. Leading on from that, making functions like this then provisioning for loads of cases you don't actually have yet. The moment you create something to support strings with extraneous whitespace for example, now you're permitting that. You WILL have badly formed strings and they'll slip through standard testing. It's not only the cases it'll try to handle but what it'll try to convert. People will add parses for things they think will be commonly needed rather than on demand.
    3. Obviously, not using standard libraries which eases the hell of a lot of things like trying to parse phone numbers. I'm library adverse for some formats because many libraries have the above problems but for some things it's really too much to DIY.

    Just at a glance, the DB2 date conversion should be somewhere in the DB2 namespace, there are libs for decimal with maths and intl, there are libs for date formats and there are libs to parse emails.

  • guest (unregistered) in reply to Peter Tramo

    no else/default? edge cases, man! edge cases! sheesh, amateurs.

  • 🤷 (unregistered) in reply to Oldtaku

    Skimming through old WTF articles and came across this comment as well. Yes, I have seen code from developers who very clearly learned coding with C and never felt the need to "upgrade" their knowledge to the current framework they are using. The code was littered with methods that did stuff that the .NET-framework already takes good care of. Need to find the last position of "/" in a string? Why, you implement your own method, of course! Because you really can't trust that pesky old ".LastIndexOf('/')' to give you the true result, right? Need to trim whitespaces? Why, you implement your own method, of course! Heaven forbid you use that ".Trim()" method! Need to "pad left" a string? Why, you implement your own method, of course! Don't you dare using that ".PadLeft(2,'0')", it's the work of the devil! And so on.

Leave a comment on “Unstrung Manager”

Log In or post as a guest

Replying to comment #:

« Return to Article