• Fregas (unregistered)

    oh god kill me now!

  • Mike R (cs)

    I am sure there's a very good excuse for this.

    Nobody would store all the data to a class in a single string without good reason. If they don't have a good reason, they should be dragged out back and shot.

  • loneprogrammer (cs)

    The real WTF here is the number of hoops you have to jump through to make Java properly align strings on machine word boundries for good performance!

  • Justin Boswell (unregistered)

    How much do you want to bet that he didn't even define toString() to return that string either?

  • shane (cs)

    head.  hurt.  must.  kill.

    proof possitive that you can't teach an old dog new tricks, but you can teach him to bark in a different language...

  • Jon Strayer (unregistered) in reply to Mike R

    If the class is a wrapper for processing records stored in a flat file then this code makes sense.

  • Rick (cs)

    It would make more sense if data was initialized:

    String data = new String( new byte[80] );

  • IDENTIFICATION DIVISION. (unregistered)

    Maybe this was developed using

    http://www.legacyj.com/legacy2.html

     

    [:O]

  • diaphanein (unregistered) in reply to IDENTIFICATION DIVISION.

    Believe it or not, people *still* do new development this way.  Needless to say, there is almost always huge conflict between the old and the new on issues like this.

    Last year, I worked on a project that had 3 distinct values stored inside of a single database column.  Every time that column was pulled out, it had to be parsed into its 3 seperate values.  Worse yet, the fields weren't fixed width.  Rather than store the values as 3 seperate database fields.  Needless to say, I took great exception at this. 

    Also found in this system were dates and numbers stored as strings rather their appropriate data types.  Very, very, very poor and non-negotiable design. 

    To this day, I still have nightmares about that system.

  • b0b0b0b (unregistered)

    That code is awesome.  It totally looks like somebody machine-translated from cobol to java and then massaged the output a little.

  • Jumbs (unregistered) in reply to diaphanein

    I have am dealing day to day with someone who decided to have a DB field with comma separated strings in it. Such as: lastname, firstname, other table's primary_key. It makes joining tables very fun. Luckily, I have found my savior for this: mysql's SUBSTRING_INDEX! Ugh, it's a nightmare.

  • JamesCurran (cs) in reply to Jumbs

    Anonymous:
    I have am dealing day to day with someone who decided to have a DB field with comma separated strings in it. Such as: lastname, firstname, other table's primary_key. It makes joining tables very fun. Luckily, I have found my savior for this: mysql's SUBSTRING_INDEX! Ugh, it's a nightmare.

    In MS SQL Server, you can have a "Computed column": a column which is not actually stored in the DB, but calculated on the fly when refered.  If mysql has such a feature, create new columns in the table (as should have been done in the first place), run a process once to split that field into the proper columns, then create a computed column as "FirstName + ',' + LastName + ',' + OtherColumn"

    Then, you can use the column as the Good Lord intended, and any legacy code can read the comma separated field as it expects.  The only things that must be changed are places the try to write to the CS field, but the separate fields should make that code simplier..

     

  • bat (cs) in reply to diaphanein

    I have to admit: I'm just about to rebuild an SQL database to use string dates.  It's a database of awards given by past and present royalty in my kingdom in the Society for Creative Anachronism.  A particular person might know, for example, that Prince Alfar gave them an Award of Arms in 1996, but they don't recall the month, or perhaps it was an Order of the Rose Leaf from Prince Brusi in May of 1992, but the day is unknown.  Rather than kick these people out of the database completely (and have them constantly email me to complain), I figured I'd store dates as yyyy-mm-dd, where the dd and mm could be replaced by ?? if necessary.  It's slightly more work to process, but it's acceptable, and as a kludgy side-effect, it means that 2005-03-?? sorts after 2005-03-31, meaning that complete dates have precedence over partial ones.

    So: string dates -- not always a bad idea.

  • joodie (cs)

    my jaw is still on the floor somewhere.

    bloody hell.

  • Free (cs) in reply to Mike R

    Mike R:
    I am sure there's a very good excuse for this.

    There always is. "The dog ate my homework too"

    I deal everyday with a product that keeps a comma separated list of guids in one field, it even puts the number of items at the front like so "3;one,two,three".

    Fun fun fun, this is a major product from a mjor company, the profile's addresses in  <FONT style="BACKGROUND-COLOR: #000000" color=#000000>Microsoft Commerce Server.</FONT>

     

     

  • goober foober (unregistered) in reply to JamesCurran
    JamesCurran:

    In MS SQL Server, you can have a "Computed column": a column which is not actually stored in the DB, but calculated on the fly when refered.  If mysql has such a feature, create new columns in the table (as should have been done in the first place), run a process once to split that field into the proper columns, then create a computed column as "FirstName + ',' + LastName + ',' + OtherColumn"

    Then, you can use the column as the Good Lord intended, and any legacy code can read the comma separated field as it expects.  The only things that must be changed are places the try to write to the CS field, but the separate fields should make that code simplier..

     

    (If using SQL Server 2K) you can create a view with the computed column and use INSTEAD OF UPDATE and INSTEAD OF INSERT triggers on the view to handle writes from the legacy code base.

     

  • Jon Limjap (cs) in reply to goober foober

    Long live woodstock! Let's go streaking y'all! [:p]

    ==================

    I'm having a hard time trying to teach an officemate VB.NET after years of being stuck in COBOL, but there is hope for her. At least she can use Collections properly nowadays, after around 6 months of making COBOL "go away".

  • yajirobe (cs)

    Some positive note:

    1. The code is created with serialization in mind. It would be a breeze to implement serialization to the object.
    2. It leverage the advantage of OOP. You don't care how an object implemented, you just glad it is encapsulated well within the particular class.
  • Drak (cs) in reply to bat

    bat:
    I figured I'd store dates as yyyy-mm-dd, where the dd and mm could be replaced by ?? if necessary.  It's slightly more work to process, but it's acceptable, and as a kludgy side-effect, it means that 2005-03-?? sorts after 2005-03-31, meaning that complete dates have precedence over partial ones.

    So: string dates -- not always a bad idea.

    Drop the '-'s and we can talk [:D]

    Drak

  • bat (cs) in reply to Drak

    Ya-huh.  I put 'em in cos there are way too many people who think the only real date format is month-day-year, and they were going to complain that 20050331 means the 5th day of the 20th month in the year 0331, and why on earth didn't I know that the Gregorian calendar wasn't in use in 331AD?

    Practically speaking, tho, I'd rather store dates with the dashes: in the unlikely event that I might one day have to hand-edit an SQL dump to fix some insanely WTF-worthy bug, I'd like to be able to see what I'm doing.  Two bytes per user is nothing compared to even such a minute improvement in debugging.

  • maribert (cs) in reply to bat

    Could you not have used separate columns for day, month and year? Then you would be able to use proper NULL values for unknown months and days. And the order would not be ambiguous.

  • Teemu (unregistered) in reply to bat

    Why didn't you store them in three columns to begin with?

    Year, Month and Day ? Then you could have null values in whichever field is unknown.

    And no parsing of strings, and easy to join...

  • zgoda (unregistered) in reply to Drak
    Drak:

    bat:
    I figured I'd store dates as yyyy-mm-dd, where the dd and mm could be replaced by ?? if necessary.  It's slightly more work to process, but it's acceptable, and as a kludgy side-effect, it means that 2005-03-?? sorts after 2005-03-31, meaning that complete dates have precedence over partial ones.

    So: string dates -- not always a bad idea.

    Drop the '-'s and we can talk [:D]

    Drak



    Use integers instead of strings, it's even more fun.
  • ammoQ (unregistered)

    Maybe the programmer wanted to save memory. Putting everything into a single string requires less memory than having a string object for every field. ;-)
    As a side effect, you can "group" fields like cobol does with the "redefines" clause: For example, if data.substring(0,9) represent field x and data.substring(10,19) represent field y, than
    data.substring(0,19) represent a composite of x and y.
    Since Cobol can do things like that, any translation of cobol programs have to find a
    way to do the same, especially it the translation is done by a program.

  • adb (unregistered) in reply to bat

    How about this as an alternative for dealing with imprecise dates?


    Instead of storing an incomplete string date, where getting the sematics right could be rather tricky, why not store two dates: an earliest possible and latest possible date?  If the date is known precisely, these would be the same of course.  That way, you allow people to be precise as they can be.

    For example, if they know they were given the award on a particular weekend, but they are not sure what day, they can be precisely imprecise ;-) and enter Friday as the earliest possible date and Sunday as the latestet possible date. By using strings, you force people into quantum date ranges, which may not accurately reflect their knowledge of the event.
  • Xepol (cs) in reply to Drak

    Hell, SQL's real support of date data is so poor, you might as well store them as integers or strings. ANYTHING that might possibly be groupable, because having to winnow throught the various vendor variations just to get data grouped by day of the week or by date is pretty much impossible to do without throwing away sql's main benefits and binding to a vendor.

    And if I gotta live with a few -'s, fine, as long as they are ALWAYS there.  Nothing worse than data that requires a fixed format but relies on humans to do it

    <SHUDDER>

  • bat (cs) in reply to adb

    An interesting solution!  The obvious rejoinder is: how is enforcing "min_date <= max_date" any easier than requiring that fuzzy_date has the required format?  In practice, no data manipulation would be done without the use of a fuzzy date class definition that handles all the validation issues, so I'll stick with the current (already half-implemented) idea, but it's good to see y'all thinking outside the box.

  • adb (unregistered) in reply to bat

    The obvious rejoinder is: how is enforcing "min_date <= max_date" any easier than requiring that fuzzy_date has the required format?

    If you are using a DBMS that supports check constraints the former is trivial.  E.g. (should work for PostgreSQL--but I didn't test it):

    create table award (
        grantor_id integer not null references member,
        recipient_id integer not null references recipient,
        min_date timestamp not null,
        max_date timestamp not null,
        description varchar not null,
        check (min_date <= max_date)
    );

  • adb (unregistered) in reply to adb

    Damn, apparently this site can't handle less-than signs very well.  The important line in my example read

    check (min_date less_than_or_equal max_date)

    Where "less_than_or_equal" should be replaced by the usual combination of characters.

  • Lothar (unregistered) in reply to Rick
    Rick:
    It would make more sense if data was initialized:

    String data = new String( new byte[80] );


    I doubt that the code was complete so there will be some part in the source coping with the initialization of data. Anyway what sense would above line make? Strings are immutable in Java, so execept of more work to do for the garbage collector initializing data with 80 ASCII-zero-characters using a deprecated constructor has no effect on the functionality of the code.


    Regards, Lothar
  • ammoQ (unregistered) in reply to adb

    why don't you just write min_date &lt;= max_date ?

  • ammoQ (unregistered) in reply to ammoQ

    oops, they got me, too

  • tmnich (cs) in reply to ammoQ

    don't be silly, just use < instead

  • Dynamite Joe (unregistered)

    So flat files are indicative of all that's wrong with the heyday of yesterday?  Hmmm... I'll be sure to tell all my Unix boxes and they're sad and pathetic relics, bound for the scrapheap.  ;)

    Seriously, if I can't have my configuration file for X in a text file, I'm a very unhappy boy -- there is absolutely no easier way to script an app.  Dumping everything into a binary file might be efficient space-wise, but that's about the only respect in which they're superior.

  • Drak (cs) in reply to zgoda
    Anonymous:
    Drak:

    Drop the '-'s and we can talk [:D]

    Drak



    Use integers instead of strings, it's even more fun.

    Integers wouldn't always be the same length. And dates as integers suck.Unless you use the ticks representation (and always use the same ticks representation).

    Drak

  • Rich Leick (unregistered)

    Reminds of this VB6 function that was written by a cobol-transformed programmer:

    function PadZeros(oldString as String, length as Integer) as String
    {
        dim i as integer
        dim retVal as String

        retVal =  oldString
        for i = 1 to length
           retVal = retVal & "0"
          
        PadZeros = retVal
    }

    It's wrong on so many levels!

  • Mr Anonymous (unregistered)

    <font size="1">I have seen this type of thing before...Old cobol code wrapped by Visual Basic COM - wrapped by C# ASP.Net -yak.

    We had to write a wrapper around the VB Com object that only has 1 property of type string but the string has fixed positions identifying certain fields.

    Some code snippets....

            public string X_FNAME_OUT {get {return GetField(Field.X_FNAME_OUT);}}
            public string X_FNAME_GEND {get {return GetField(Field.X_FNAME_GEND);}}
            public string X_SNAME_OUT {get {return GetField(Field.X_SNAME_OUT);}}
            public string X_P_ADD1_OUT {get {return GetField(Field.X_P_ADD1_OUT);}}
            public string X_P_ADD2_OUT {get {return GetField(Field.X_P_ADD2_OUT);}}
            public string X_P_ADD3_OUT {get {return GetField(Field.X_P_ADD3_OUT);}}
            public string X_P_ADD4_OUT {get {return GetField(Field.X_P_ADD4_OUT);}}
            public string X_P_ADD5_OUT {get {return GetField(Field.X_P_ADD5_OUT);}}
            public string X_P_PCODE_OUT {get {return GetField(Field.X_P_PCODE_OUT);}}
            public string X_P_SUBCODE {get {return GetField(Field.X_P_SUBCODE);}}
            public string X_P_NGCODE {get {return GetField(Field.X_P_NGCODE);}}

    ....

    private void SetField(Field field, string data)
            {
                int iFieldIndex = (int)field;
                int MaxLength = (int)IValueFields[iFieldIndex, FieldLength];

                data = data.ToUpper();

                switch(field)
                {   
                    case Field.X_P_ADD1_IN:
                    case Field.X_P_ADD2_IN:
                    case Field.X_P_ADD3_IN:
                    case Field.X_P_ADD4_IN:
                    case Field.X_P_ADD5_IN:
                    case Field.X_R_ADD1_IN:
                    case Field.X_R_ADD2_IN:
                    case Field.X_R_ADD3_IN:
                    case Field.X_R_ADD4_IN:
                    case Field.X_R_ADD5_IN:
                        data = data.Replace(@"P O BOX", @"PO BOX"); //Fix
                        break;

                    default:
                        break;
                }

                if (data.Length > MaxLength)
                {
                    throw new IValueWrapperException(@"Data exceeds maximum length of input field " + field.ToString());
                }

                data = data.PadRight(MaxLength, ' ');
                IValueFields[iFieldIndex, FieldData] = data;
            }

    ....

                IValueObj.InputStr = this.ToString();
                IValueObj.RunIVJ2CVB();
                ExtractData(IValueObj.OutputStr.ToString());

    And the company responsible for this Modern COBOL mess - http://www.intimatedata.co.za/
    </font>

  • cm5400 (cs)

    This makes me want to run for the hills.  [:S]

  • dubwai (cs)

    OK.  All respect to the host but the explanation is a little off.

    This code is a Java converting data to and from a copybook retrieved from a Mainframe.  The data format is not the WTF.

    The WTF is that instead of defining this class as a collection of field Objects that define the length and type of each field in the copybook and calculate the offsets on loading of the class, the developers copied the basically the same method, with the same local variables, about 500 - 1000 times (There are many classes like this.)  Notice that getCUSTOMER_NBR() doesn't call getRawCUSTOMER_NBR(), it's a duplication of the same method with an extra line of code.

    Another WTF is the way repeating records are indexed and retrieved.  Why does it find the field and the add the length of the repeating records to that offset instead of finding the correct repeating record and grabbing the field.

    The other WTF is that each of these classes is about 2000 lines long.  Whoever developed this didn't put the methods in the same order as the fields.  That means if any of the fields in the middle of the copy book have to be resized, you would have to go through and search back and forth adding the length of each field to the last and use that to update the offset of three methods for every field.

  • loneprogrammer (cs) in reply to Dynamite Joe
    Anonymous:

    Seriously, if I can't have my configuration file for X in a text file, I'm a very unhappy boy

    Config files and databases are very different things.

  • dubwai (cs) in reply to Dynamite Joe

    Anonymous:
    So flat files are indicative of all that's wrong with the heyday of yesterday?  Hmmm... I'll be sure to tell all my Unix boxes and they're sad and pathetic relics, bound for the scrapheap.  ;)

    Seriously, if I can't have my configuration file for X in a text file, I'm a very unhappy boy -- there is absolutely no easier way to script an app.  Dumping everything into a binary file might be efficient space-wise, but that's about the only respect in which they're superior.

    Not sure who you are replying to here but config files are normally not fixed length records like this code deals with.

  • Stephan Rose (unregistered) in reply to Mike R

    Mike R:
    I am sure there's a very good excuse for this.

    Nobody would store all the data to a class in a single string without good reason. If they don't have a good reason, they should be dragged out back and shot.

    Co-worker I had once did....

    I spent days removing SetBlah(string shootMeNow) functions....and replacing them with properties with the appropriate type (this is C#)

    As an added bonus, his code many times resulted in stuff like stringVar.ToString() and other atrocities.

  • gid79 (cs) in reply to Stephan Rose

    I spent a good couple of years working with a framework like the above. It was designed to interept a network api for an AS/400 host system. The protocol was (and still is) a series of fix width buffers passed over TCP to and from the host.

    We had a little tool to generate the classes for each record type, which link the above had a nuch of getters that accessed the underlying buffer by sections.

    I didn't think it was to bad at the time....having said that if this is hand written then...WTF

  • dubwai (cs) in reply to gid79

    gid79:

    We had a little tool to generate the classes for each record type, which link the above had a nuch of getters that accessed the underlying buffer by sections.

    I didn't think it was to bad at the time....having said that if this is hand written then...WTF

    Thank you.  Someone gets it.

    Not only is it hand written, it's copy and paste code.  They could have at least defined a class for each field such that the offsets could be automatically determined from the lengths of the fields.

  • Rob (unregistered)

    Interesting to see the comments on this piece of code since (unless there is an astounding coincidence) it is part of an application that I worked on.  A few of you got it sort of right, though not entirely.  It is output from a program that reads COBOL copybooks and generates Java classes which understand the format described by the copybook, and can read or write strings in that format.  The field names are taken directly from the copybook, thus the uppercasing.  Of course it could be done better, but in the scheme of things it was written for a company whose core business is not producing software or even close to it, so spending more time building the perfect code generator was not funded (and in 1998 when this was written there were no products on the market for it).  The more annoying WTF is that I see people still using this program and then hand tweaking the generated code, insuring later breakage if it is ever regenerated.  Anyway, highly amusing to see it mentioned here.

  • dubwai (cs) in reply to Rob

    Anonymous:
    Interesting to see the comments on this piece of code since (unless there is an astounding coincidence) it is part of an application that I worked on.  A few of you got it sort of right, though not entirely.  It is output from a program that reads COBOL copybooks and generates Java classes which understand the format described by the copybook, and can read or write strings in that format.  The field names are taken directly from the copybook, thus the uppercasing.  Of course it could be done better, but in the scheme of things it was written for a company whose core business is not producing software or even close to it, so spending more time building the perfect code generator was not funded (and in 1998 when this was written there were no products on the market for it).  The more annoying WTF is that I see people still using this program and then hand tweaking the generated code, insuring later breakage if it is ever regenerated.  Anyway, highly amusing to see it mentioned here.

    I know of no code generator for this and it's part of a subsystem that is completely unstable and unreliable.  Messages produced by it have taken weeks to find their recipeint.  I find it unlikely that it will be regenerated, especially not to add one field.  It's more likely be relegated to the trash bin.

  • Rob (unregistered) in reply to dubwai

    This is why I find the thread amusing, it just highlights that code can look silly if you don't know it's background or context.  That you didn't know this is from a generator is a perfect example.  I mean the comments about this being written by a cobol developer, or trying to align on word boundaries etc.. lol.  Don't get me wrong, the code has some definite issues but it is more along the lines of poor handling of txn versions and field redefinitions.  Feel free to fix it :)

    x22288

  • dubwai (cs) in reply to Rob
    Anonymous:

    This is why I find the thread amusing, it just highlights that code can look silly if you don't know it's background or context.  That you didn't know this is from a generator is a perfect example.  I mean the comments about this being written by a cobol developer, or trying to align on word boundaries etc.. lol.  Don't get me wrong, the code has some definite issues but it is more along the lines of poor handling of txn versions and field redefinitions.  Feel free to fix it :)

    Perhaps you are right.  Sometimes frustration gets the best of me.  Not being able to fix the issues that plague me is frustrating.

    I guess the real WTF is not having the generator anymore.

  • wow gold (unregistered)
    Comment held for moderation.
  • Yusaku (unregistered)

    Ok, I'm beating a really long-dead horse here... But I do have a feeling I know the source system and why is it done in this way. Let's just say that the "N" stands for "New" and yes, it comes from early 70s. Since the "B" stands for "Billing", it contains a LOT of aggregated knowledge, even though it is in ugly format. Around the year of this WTF publication, the company in question invested massive amounts of money to bring their "ugly", "text-interface" and whatever IT-pejorative words you could think of up to current standards of java-ness, XML-ness etc. The party went on for about 4 years, at which point it was stopped, everyone was let out and billing is still done on NBR. It does have a lot of it's idiosyncrasies, but it has one feature all the systems that tried afterwards failed at - it works.

    Surprisingly, that counts way over the code cleanness in the end.

    I believe that the code itself was likely from import layer only, so the comment from yajirobe is spot-on. Well - if this code is NOT from import layer and NBR was indeed to be rewritten wholly to java in this way, that would explain why the project failed, on the other hand :-)

Leave a comment on “Party Like It's 1969”

Log In or post as a guest

Replying to comment #:

« Return to Article