• (cs) in reply to Anon
    Anon:
    1. What is the try/catch for? Sure you wouldn't expect StringBuffer.append to throw an exception unless you are running out of memory or something, but a try/catch that rarely (if ever) actually throws an exception probably has little performance impact.

    WTF! He is catching RuntimeException! That logger better be prepared to handle the death of the thread it is being executed on.

    Even more disturbing... Why TF did the developer decided he nees to catch RuntimeException? It wasn't because of a compiler warning, that is for sure.

  • Ben (unregistered) in reply to Procedural
    Procedural:
    Catching it as it occurs as a quick-hack way of knowing how long your string can be (perhaps to show that information to the user, e.g., do not export anything beyond the sales records for Ohio) is not a bad idea

    All it did was log the exception. There's no way for the user to figure out which string was the problem or even how long it got. And then, it would continue running, so you'd have some silently corrupt data passed back, and no idea which entry in the log file corresponded to it.

    This would actually make debugging many times harder.

    2. It was probably a shortened method name

    Shortened to the point of saying the opposite of what it did.

  • Anonymously Yours (unregistered)

    I'll admit my C++ is a little rusty, but I am pretty sure that function is a memory leak. Even if it's C# (where garbage collection would hopefully clean this up before too long), does it really need to instantiate a new StringBuffer on every function call?

  • Squire (unregistered) in reply to no one
    no one:
    I think it's worth noting that in Java the plus operator actually uses a StringBuffer behind the scenes anyway, so constructing your own in this simple case just adds needless wordiness.

    Also, I hate these terrible catch blocks. Do you really want to return an empty string when there's an error? REALLY??

    Not only does using a StringBuffer yourself result in needless wordiness, it also generates more bytecode. If you use String concatenation over a StringBuilder, it'll be simpler:

    public class Test {
      public static void main(String arg[]) {
        System.out.println(methodA("test"));
        System.out.println(methodB("test"));
      }
      public static String methodA(String s) {
        StringBuilder sb = new StringBuilder();
        char c = '"';
        sb.append(c);
        sb.append(s);
        sb.append(c);
        return sb.toString();
      }
      public static String methodB(String s) {
        return '"' + s + '"';
      }
    }
    public static java.lang.String methodA(java.lang.String);
      Code:
       Stack=2, Locals=3, Args_size=1
       0:	new	#7; //class java/lang/StringBuilder
       3:	dup
       4:	invokespecial	#8; //Method java/lang/StringBuilder."<init>":()V
       7:	astore_1
       8:	bipush	34
       10:	istore_2
       11:	aload_1
       12:	iload_2
       13:	invokevirtual	#9; //Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
       16:	pop
       17:	aload_1
       18:	aload_0
       19:	invokevirtual	#10; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       22:	pop
       23:	aload_1
       24:	iload_2
       25:	invokevirtual	#9; //Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
       28:	pop
       29:	aload_1
       30:	invokevirtual	#11; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       33:	areturn
    public static java.lang.String methodB(java.lang.String);
      Code:
       Stack=2, Locals=1, Args_size=1
       0:	new	#7; //class java/lang/StringBuilder
       3:	dup
       4:	invokespecial	#8; //Method java/lang/StringBuilder."<init>":()V
       7:	bipush	34
       9:	invokevirtual	#9; //Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
       12:	aload_0
       13:	invokevirtual	#10; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       16:	bipush	34
       18:	invokevirtual	#9; //Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
       21:	invokevirtual	#11; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       24:	areturn

    I realize the code isn't the same in both examples, I took the original method and changed it to what I would probably write (if I wrote something like that).

    As for returning an empty String if a RuntimeException occurs: If a RuntimeException occurs when you're prepending and appending quotation marks to a String, you probably shouldn't continue as if nothing is wrong. Letting that RuntimeException bubble up to someplace you can actually do something about it, like displaying "Fatal error, program can not continue" to the user would be better. This assumes you can even do that. Once a RuntimeException has occurred, it's unlikely you will be successful trying to build a message and dialog box to display to the user.

  • Squire (unregistered) in reply to Anonymously Yours
    Anonymously Yours:
    I'll admit my C++ is a little rusty, but I am pretty sure that function is a memory leak. Even if it's C# (where garbage collection would hopefully clean this up before too long), does it really need to instantiate a new StringBuffer on every function call?

    Your C++ is so rusty you don't even recognize that it is Java, not C++ or C#.

    Regardless, even

    return '"' + str + '"';
    instantiates a new StringBuilder on every method call, so you aren't gaining or losing anything doing it yourself (although as I showed in an earlier comment, letting the compiler do is a lot easier on you).

  • Moof (unregistered) in reply to frits

    80% of the time.

  • Squire (unregistered) in reply to Procedural
    Procedural:
    Not great code, but not as much of a WTF as you might think:
    1. Anybody who has done database exports and imports of large data sets knows that memory (and memory limitation errors) is a persistently nagging problem. Catching it as it occurs as a quick-hack way of knowing how long your string can be (perhaps to show that information to the user, e.g., do not export anything beyond the sales records for Ohio) is not a bad idea if you can't afford to double-parse your data set (once to count and pre-allocate the required amount of memory without going hog-wild on multiples, once to directly set the strings in place without using stack- or heap-costly concatenation.)

    Verdict: Story: meh. Code: not WTF-worthy.

    What? Really, what?

    You think the best place to deal with your program running out of memory is in a method that prepends and appends a quotation mark to a String? Really?

    Really? You really think that's the best place to deal with your program running out of memory?

    Wow. Just... wow.

    You should read http://java.sun.com/docs/books/tutorial/essential/exceptions/catchOrDeclare.html:

    The third kind of exception is the runtime exception. These are exceptional conditions that are internal to the application, and that the application usually cannot anticipate or recover from.

    Also good reading http://c2.com/cgi/wiki?DontCatchRuntimeExceptions

    Verdict: Your comment is the real WTF.

  • (cs) in reply to no one
    no one:
    I think it's worth noting that in Java the plus operator actually uses a StringBuffer behind the scenes anyway, so constructing your own in this simple case just adds needless wordiness.

    Also, I hate these terrible catch blocks. Do you really want to return an empty string when there's an error? REALLY??

    I believe current JVMs use StringBuilder behind the scenes, so the StringBuffer reference is worse than needless, adding unnecessary synchronization.

  • (cs) in reply to Squire
    Squire:
    no one:
    I think it's worth noting that in Java the plus operator actually uses a StringBuffer behind the scenes anyway, so constructing your own in this simple case just adds needless wordiness.

    Also, I hate these terrible catch blocks. Do you really want to return an empty string when there's an error? REALLY??

    Not only does using a StringBuffer yourself result in needless wordiness, it also generates more bytecode. If you use String concatenation over a StringBuilder, it'll be simpler:

    (snip)

    I realize the code isn't the same in both examples, I took the original method and changed it to what I would probably write (if I wrote something like that).

    Yup, the equivalent to your concatenation example would be:

        return new StringBuilder().append('"').append(s).append('"').toString();

    This produces the same bytecode, but as you say it's not idiomatic Java code.

  • Procedural (unregistered) in reply to Squire
    Squire:
    Procedural:
    Not great code, but not as much of a WTF as you might think:
    1. Anybody who has done database exports and imports of large data sets knows that memory (and memory limitation errors) is a persistently nagging problem. Catching it as it occurs as a quick-hack way of knowing how long your string can be (perhaps to show that information to the user, e.g., do not export anything beyond the sales records for Ohio) is not a bad idea if you can't afford to double-parse your data set (once to count and pre-allocate the required amount of memory without going hog-wild on multiples, once to directly set the strings in place without using stack- or heap-costly concatenation.)

    Verdict: Story: meh. Code: not WTF-worthy.

    What? Really, what?

    You think the best place to deal with your program running out of memory is in a method that prepends and appends a quotation mark to a String? Really?

    Really? You really think that's the best place to deal with your program running out of memory?

    Wow. Just... wow.

    You should read http://java.sun.com/docs/books/tutorial/essential/exceptions/catchOrDeclare.html:

    The third kind of exception is the runtime exception. These are exceptional conditions that are internal to the application, and that the application usually cannot anticipate or recover from.

    Also good reading http://c2.com/cgi/wiki?DontCatchRuntimeExceptions

    Verdict: Your comment is the real WTF.

    Oh man, you must be so popular with the girls. Yes, the smallest atom of text that you add to a string is the best place to figure out, while debugging a data dump, if and where you have a problem. Your two other options are at the character level (useless) or at the memroy allocation level where you are so far off the call stack that you have to back-track to find exactly what was going on. Place a breakpoint on the log command there and you have an OK, not great, not bad, way of figuring this out. Looks to me like debug code growing up to be something else. You don't like my answer ? Try building real-world systems then.

    Verdict: Your ignorance of practice and pragmatics is the real WTF.

  • Anonymously Yours (unregistered) in reply to Squire
    Squire:
    Anonymously Yours:
    I'll admit my C++ is a little rusty, but I am pretty sure that function is a memory leak. Even if it's C# (where garbage collection would hopefully clean this up before too long), does it really need to instantiate a new StringBuffer on every function call?

    Your C++ is so rusty you don't even recognize that it is Java, not C++ or C#.

    Regardless, even

    return '"' + str + '"';
    instantiates a new StringBuilder on every method call, so you aren't gaining or losing anything doing it yourself (although as I showed in an earlier comment, letting the compiler do is a lot easier on you).
    Ah, yes, you're correct. My memory is playing tricks on me today; I confused an implementation of StringBuffer for C++ as being standard to the language.

    I am going to go get more coffee...

  • Quijibo (unregistered)

    By "InsertComma", I assume the developer meant "InsertInvertedCommas" (i.e. quotation marks), but used "InsertComma" for brevity.

  • Prof (unregistered) in reply to NightDweller
    NightDweller:
    akatherder:
    Daniil:
    Ha. I find that code very funny. Funny as in the most useless and pointless and CPU consuming from time sharing hardworking operating system way. Luckily for us, people who write those kinds of code exist in every line of industry or life and generally have ratio of 8 to 2 thus keeping life interesting. Who's up for a drink to talk about good looking famous people?

    The ratio is more like 12 to 3 in my experience.

    to put it in plain terms what akatherder is saying is that the ration should be about 2^32 to 2^30.

    The actual number of dumb programmers in the world is:

    2^32 -2

    The -2 is you and me, but I'm starting to wonder about you.

    (fifth post attempt)

  • (cs) in reply to bleech
    bleech:
    frits:
    oops:
    frits:
    Occasional Reader:
    akatherder:
    Daniil:
    Ha. I find that code very funny. Funny as in the most useless and pointless and CPU consuming from time sharing hardworking operating system way. Luckily for us, people who write those kinds of code exist in every line of industry or life and generally have ratio of 8 to 2 thus keeping life interesting. Who's up for a drink to talk about good looking famous people?

    The ratio is more like 12 to 3 in my experience.

    That's far too optimistic. Try 28 to 7

    Ha! I'd go as far as to say 80%.

    and by 80 you mean 75?

    No. Learn how to count. 4 out of 5 idiots think 75% is 80%.

    successful troll is successful

    72% of all statistics are just made up on the spot.

  • Anon (unregistered) in reply to Quijibo
    Quijibo:
    By "InsertComma", I assume the developer meant "InsertInvertedCommas" (i.e. quotation marks), but used "InsertComma" for brevity.

    Really? You think? http://thedailywtf.com/Comments/Insert-Comma.aspx#294939

  • HUH (unregistered) in reply to Squire
    Squire:
    no one:
    I think it's worth noting that in Java the plus operator actually uses a StringBuffer behind the scenes anyway, so constructing your own in this simple case just adds needless wordiness.

    Also, I hate these terrible catch blocks. Do you really want to return an empty string when there's an error? REALLY??

    Not only does using a StringBuffer yourself result in needless wordiness, it also generates more bytecode. If you use String concatenation over a StringBuilder, it'll be simpler:

    Yeah it would be simpler but using a StringBuilder would opt for better performance. Concatenation via "+" is literally translated into a StringBuilder at runtime.

  • Procedural (unregistered) in reply to Ben

    [quote user="Ben"][quote user="Procedural"] [quote]2. It was probably a shortened method name[/quote]

    Shortened to the point of saying the opposite of what it did.[/quote]

    Who said the original developer (and not some intern or junior) shortened it ? If we look at the name of the method and try to figure out the code it taints our perception. Of course in theory all method and variable names are great, code is self-documenting, reference manuals are written and code is shipped on time without management pressuring people for one more feature the night before a release. In real life though, with many people looking at and tweaking code, it is best in moments of doubt to try to infer the meaning before trashing the whole code. Other people are smart too. In this case, put a breakpoint on the logger, and I can see a few good uses for that.

  • SeriousStuff (unregistered) in reply to Squire

    I think a couple of things are making the byte code in the more verbose version longer:

    Instead of using a constant '"', you're actually assigning that constant to a variable, then passing the value of that variable into the append() method. The operator+ version uses a constant instead, which eliminates the need to store and load a variable during initialization and use.

    Another difference seems to be assigning the StringBuilder to a variable. Again, extra loads and stores because of that. The operator+ version seems to just use the reference at the top of the stack. Which seems silly, I mean you'd figure the java compiler could have optimized out the store, since the variable isn't used outside of the method.

    Then again, the invoke virtuals seems equally silly for the same reason. In C++, StringBuilder would be a stack variable, making calls to its methods non-virtual.

    I wonder (can't try it right now), doing something like:

    return new StringBuilder().append('"').append(s).append('"');

    would give bytecode similar to the operator+'s code?

  • (cs) in reply to Procedural
    Procedural:
    Squire:
    Procedural:
    Not great code, but not as much of a WTF as you might think:
    1. Anybody who has done database exports and imports of large data sets knows that memory (and memory limitation errors) is a persistently nagging problem. Catching it as it occurs as a quick-hack way of knowing how long your string can be (perhaps to show that information to the user, e.g., do not export anything beyond the sales records for Ohio) is not a bad idea if you can't afford to double-parse your data set (once to count and pre-allocate the required amount of memory without going hog-wild on multiples, once to directly set the strings in place without using stack- or heap-costly concatenation.)

    Verdict: Story: meh. Code: not WTF-worthy.

    What? Really, what?

    You think the best place to deal with your program running out of memory is in a method that prepends and appends a quotation mark to a String? Really?

    Really? You really think that's the best place to deal with your program running out of memory?

    Wow. Just... wow.

    You should read http://java.sun.com/docs/books/tutorial/essential/exceptions/catchOrDeclare.html:

    The third kind of exception is the runtime exception. These are exceptional conditions that are internal to the application, and that the application usually cannot anticipate or recover from.

    Also good reading http://c2.com/cgi/wiki?DontCatchRuntimeExceptions

    Verdict: Your comment is the real WTF.

    Oh man, you must be so popular with the girls. Yes, the smallest atom of text that you add to a string is the best place to figure out, while debugging a data dump, if and where you have a problem. Your two other options are at the character level (useless) or at the memroy allocation level where you are so far off the call stack that you have to back-track to find exactly what was going on. Place a breakpoint on the log command there and you have an OK, not great, not bad, way of figuring this out. Looks to me like debug code growing up to be something else. You don't like my answer ? Try building real-world systems then.

    Verdict: Your ignorance of practice and pragmatics is the real WTF.

    I assume you're pulling our legs. The stack trace when you run out of memory would get you to exactly the same method as the catch() block. As to why you've run out of memory, it's unlikely to be in this method - and without using a profiler you're unlikely to know.

  • Procedural (unregistered) in reply to java.lang.Chris;
    java.lang.Chris;:
    Procedural:
    Squire:
    Procedural:
    Not great code, but not as much of a WTF as you might think:
    1. Anybody who has done database exports and imports of large data sets knows that memory (and memory limitation errors) is a persistently nagging problem. Catching it as it occurs as a quick-hack way of knowing how long your string can be (perhaps to show that information to the user, e.g., do not export anything beyond the sales records for Ohio) is not a bad idea if you can't afford to double-parse your data set (once to count and pre-allocate the required amount of memory without going hog-wild on multiples, once to directly set the strings in place without using stack- or heap-costly concatenation.)

    Verdict: Story: meh. Code: not WTF-worthy.

    What? Really, what?

    You think the best place to deal with your program running out of memory is in a method that prepends and appends a quotation mark to a String? Really?

    Really? You really think that's the best place to deal with your program running out of memory?

    Wow. Just... wow.

    You should read http://java.sun.com/docs/books/tutorial/essential/exceptions/catchOrDeclare.html:

    The third kind of exception is the runtime exception. These are exceptional conditions that are internal to the application, and that the application usually cannot anticipate or recover from.

    Also good reading http://c2.com/cgi/wiki?DontCatchRuntimeExceptions

    Verdict: Your comment is the real WTF.

    Oh man, you must be so popular with the girls. Yes, the smallest atom of text that you add to a string is the best place to figure out, while debugging a data dump, if and where you have a problem. Your two other options are at the character level (useless) or at the memroy allocation level where you are so far off the call stack that you have to back-track to find exactly what was going on. Place a breakpoint on the log command there and you have an OK, not great, not bad, way of figuring this out. Looks to me like debug code growing up to be something else. You don't like my answer ? Try building real-world systems then.

    Verdict: Your ignorance of practice and pragmatics is the real WTF.

    I assume you're pulling our legs. The stack trace when you run out of memory would get you to exactly the same method as the catch() block. As to why you've run out of memory, it's unlikely to be in this method - and without using a profiler you're unlikely to know.

    True about java's stack dump, I don't use java though. It never seems to fit well in the solutions we look for when we look for either speed of execution, speed of iterative development or availability of labour in this area. Beyond the syntax and pecularities of Java though (which you can harp on, but it won't change the core point), the pattern is clear.

    As for memory, it is exactly likely to crash there. A quick glance at the suggested use of the code suggests that the stability of the app depends on the whole return value (here, a CSV output of a table) to fit into useable memory. If your query is too large, nothing here will protect you. You will run out of memory. A better solution is to write the results to a constrained file buffer that is flushed at regular intervals (ex, integer multiples of the block size of the storage device) and one last time at the end, rather than build it up in one heap or stack variable. Then at least you have more leeway before you need to build code defenses against queries that return too large a data set.

    Again, this looks to me like evolving code, nothing final. I think we'd all look terrible if our transient, hackish, not-meant-for-prod code was shown here. There's some value in it, and better WTF articles have been posted. Slow day I guess.

  • Outtascope (unregistered) in reply to Anon
    Anon:
    1. What is the try/catch for? Sure you wouldn't expect StringBuffer.append to throw an exception unless you are running out of memory or something, but a try/catch that rarely (if ever) actually throws an exception probably has little performance impact.

    Jamming my thumb up my arse while I wait for code to compile will have little performance impact on my executable, but I'm confident that my coworkers would consider such an act a significant WTF.

    If you don't know what you are trying to catch, then WTF are you trying to catch it? I'm quite sure that if this little section has this kind of cruft in it, then I probably don't want to maintain the rest of the code. In fact, based on this code, I'm just sure that somewhere in that inherited project you will find something beautiful like this:

    statement.execute("insert into accounts (username, pasword, bankacctid) values (" +
      insertComma(username) + "," +
      insertComma(password) + "," + 
      insertComma(bankacctid) + ")");
    

    where username, password, and bankacctid are just holders for (unsanitized) request params.

    captcha: nulla - a flavorless wafer

  • Christian (unregistered)

    As for question 3, maybe the author fondly remembers his typography lessons and uses "commas" instead of "quotes":

    http://en.wikipedia.org/wiki/Quotation_mark

  • stuff (unregistered) in reply to HUH

    If by "runtime" you mean "the time when the compiler runs"...

  • (cs) in reply to Procedural
    Procedural:
    Anybody who has done database exports and imports of large data sets knows that memory (and memory limitation errors) is a persistently nagging problem. Catching it as it occurs as a quick-hack way of knowing how long your string can be (perhaps to show that information to the user, e.g., do not export anything beyond the sales records for Ohio) is not a bad idea if you can't afford to double-parse your data set (once to count and pre-allocate the required amount of memory without going hog-wild on multiples, once to directly set the strings in place without using stack- or heap-costly concatenation.)
    But it won't work.

    As with all truly serious problems, Java signals out-of-memory with an Error subclass, not a RuntimeException subclass. That code can't fail in the way you describe. Nor can it fail and hit that exception at all since the delimiter handling won't fail and even a null String won't cause an exception. It's a useless cargo-cultism, a piece of voodoo exception handling that has been waved around some perfectly innocent code in an effort to make the author of it feel a bit better, all to no effect.

    Of course, the most serious WTFs are the things it doesn't do, of which failing to deal with embedded delimiters is the most serious (because it makes the code wrong). I'd suggest telling the culprit about little Bobby Tables, but I really doubt they'd learn the right lesson…

  • Outtascope (unregistered) in reply to Procedural
    Procedural:
    As for memory, it is exactly likely to crash there. A quick glance at the suggested use of the code suggests that the stability of the app depends on the whole return value ...

    Then why catch a RuntimeException when you want to catch an Error (which would not be caught by this block anyway)?

    If someone can tell me any instance in which this block would throw a RuntimeException, I'd love to learn about it.

  • Ben (unregistered) in reply to Procedural
    Procedural:
    Again, this looks to me like evolving code, nothing final. I think we'd all look terrible if our transient, hackish, not-meant-for-prod code was shown here.

    What would really look awful is if we claimed that code actually works / makes sense/ is good when it plainly doesn't and isn't.

  • Java Refugee (unregistered) in reply to Squire

    The StringBuffer use indicates this predates jre1.5, and the compiler optimization that came with it. Using a StringBuffer was the preferred, recommended solution over direct String concatenation.

    See http://java.sun.com/developer/JDCTechTips/2002/tt0305.html

    Or the first edition of "Effective Java" or really anything that is older than 1.5 which all pretty much agree on this topic.

    Of course, the code then goes on to use string concatenation anyways, and the method name is still silly.

  • Frz (unregistered) in reply to Mcoder
    Mcoder:
    WTF! He is catching RuntimeException! That logger better be prepared to handle the death of the thread it is being executed on.

    You (and others here) bore me. Please please if you have no idea about java exceptions don't even try to sound smart.

    ThreadDeath (and OutOfMemoryError) are both Errors not Exceptions, they inherit directly from Throwable and not from Exception (like RuntimException does)

    I don't see any way for a RuntimeException to be thrown in that piece of code (atleast not when run with a correct/java compatible classpath) - safe from runtime bytecode manipulation that is. StringBuffer and Builder gracefully handle null inputs when appending.

  • Java Refugee (unregistered) in reply to Frz
    Frz:
    I don't see any way for a RuntimeException to be thrown in that piece of code (atleast not when run with a correct/java compatible classpath) - safe from runtime bytecode manipulation that is. StringBuffer and Builder gracefully handle null inputs when appending.

    Indeed, if StringBuffer starts throwing runtime exceptions you have bigger worries than correct String escaping.

  • (cs) in reply to Frz
    Frz:
    Mcoder:
    WTF! He is catching RuntimeException! That logger better be prepared to handle the death of the thread it is being executed on.

    You (and others here) bore me. [...snip boring part...]

    Really? I've always thought the use of exclamation marks adds excitement.

  • Procedural (unregistered) in reply to Ben
    Ben:
    Procedural:
    Again, this looks to me like evolving code, nothing final. I think we'd all look terrible if our transient, hackish, not-meant-for-prod code was shown here.

    What would really look awful is if we claimed that code actually works / makes sense/ is good when it plainly doesn't and isn't.

    Yes, the Java zombies now have their moment of glory tripping people up on minutia and arcana (something Java isn't known for at all). Enjoy it. See you in a few years for your next opportunity.

  • (cs)

    I assume the try-catch is from earlier code times when there was no StringBuffer/Stringbuilder and the code was just [code]str = '"' + str + '"';[code]

    If I remember correct that could throw a Nullpointer Exception if str was null - in times of Java 1.2

  • Biter (unregistered) in reply to Procedural
    Procedural:
    True about java's stack dump, I don't use java though. It never seems to fit well in the solutions we look for when we look for either speed of execution, speed of iterative development or availability of labour in this area. Beyond the syntax and pecularities of Java though (which you can harp on, but it won't change the core point), the pattern is clear.

    As for memory, it is exactly likely to crash there. A quick glance at the suggested use of the code suggests that the stability of the app depends on the whole return value (here, a CSV output of a table) to fit into useable memory. If your query is too large, nothing here will protect you. You will run out of memory. A better solution is to write the results to a constrained file buffer that is flushed at regular intervals (ex, integer multiples of the block size of the storage device) and one last time at the end, rather than build it up in one heap or stack variable. Then at least you have more leeway before you need to build code defenses against queries that return too large a data set.

    Again, this looks to me like evolving code, nothing final. I think we'd all look terrible if our transient, hackish, not-meant-for-prod code was shown here. There's some value in it, and better WTF articles have been posted. Slow day I guess.

    Nice trolling. Go back to whatever hole you crawled out of.

  • Procedural (unregistered) in reply to Biter
    Biter:
    Procedural:
    True about java's stack dump, I don't use java though. It never seems to fit well in the solutions we look for when we look for either speed of execution, speed of iterative development or availability of labour in this area. Beyond the syntax and pecularities of Java though (which you can harp on, but it won't change the core point), the pattern is clear.

    As for memory, it is exactly likely to crash there. A quick glance at the suggested use of the code suggests that the stability of the app depends on the whole return value (here, a CSV output of a table) to fit into useable memory. If your query is too large, nothing here will protect you. You will run out of memory. A better solution is to write the results to a constrained file buffer that is flushed at regular intervals (ex, integer multiples of the block size of the storage device) and one last time at the end, rather than build it up in one heap or stack variable. Then at least you have more leeway before you need to build code defenses against queries that return too large a data set.

    Again, this looks to me like evolving code, nothing final. I think we'd all look terrible if our transient, hackish, not-meant-for-prod code was shown here. There's some value in it, and better WTF articles have been posted. Slow day I guess.

    Nice trolling. Go back to whatever hole you crawled out of.

    Disagreement isn't trolling (unless you live in a totalitarian state of something). If you wish to see an example of trolling, pick up any samples of your own writing.

  • Onaka (unregistered)

    I think this is quite a non wtfy wtf.

    Say this would have been coded in C or something where you dont have such an incredibly clever compiler. Then you might just want to create a function for this purpose (that calls sprintf or something). A wtf that is a wtf only because of a clever language is not a very good wtf.

    Where are those really fucked up examples i miss so much?!

  • the one (unregistered) in reply to Rick
    Rick:
    bleech:
    frits:
    oops:
    frits:
    Occasional Reader:
    akatherder:
    Daniil:
    Ha. I find that code very funny. Funny as in the most useless and pointless and CPU consuming from time sharing hardworking operating system way. Luckily for us, people who write those kinds of code exist in every line of industry or life and generally have ratio of 8 to 2 thus keeping life interesting. Who's up for a drink to talk about good looking famous people?

    The ratio is more like 12 to 3 in my experience.

    That's far too optimistic. Try 28 to 7

    Ha! I'd go as far as to say 80%.

    and by 80 you mean 75?

    No. Learn how to count. 4 out of 5 idiots think 75% is 80%.

    successful troll is successful

    72% of all statistics are just made up on the spot.

    And 60% of the time, it works every time.

  • (cs) in reply to Stephen
    Stephen:
    It does not matter. Had he just concatenated the strings, the compiler would have used a StringBuilder anyway.

    Not if it is C# - I'm not convinced this is Java, and if it's C# then string concatenation results in some wonky stuff behind the scenes... it is still crap though.

  • PetervF (unregistered) in reply to Procedural
    Procedural:
    True about java's stack dump, I don't use java though. It never seems to fit well in the solutions we look for when we look for either speed of execution, speed of iterative development or availability of labour in this area.

    If you're looking for both speed of execution and development speed java and comparable languages are actually a nice middle ground.

    Procedural:
    As for memory, it is exactly likely to crash there. A quick glance at the suggested use of the code suggests that the stability of the app depends on the whole return value (here, a CSV output of a table) to fit into useable memory.

    Which is why just truncating a string is a silly idea. What's the point of an export that may or may not contain all the data requested?

    Procedural:
    If your query is too large, nothing here will protect you. You will run out of memory. A better solution is to write the results to a constrained file buffer that is flushed at regular intervals (ex, integer multiples of the block size of the storage device) and one last time at the end, rather than build it up in one heap or stack variable. Then at least you have more leeway before you need to build code defenses against queries that return too large a data set.

    And you didn't want to use java because of development speed?

    OutputStream out = new BufferedOutputStream(new FileOutputStream(...));
    
    Procedural:
    Disagreement isn't trolling (unless you live in a totalitarian state of something). If you wish to see an example of trolling, pick up any samples of your own writing.

    It's just that it's difficult to believe that you'd consider handling out-of-memory errors in some random function by ignoring (but logging) the problem to be a good idea. Either you anticipated that you might not have enough memory and you should have written your code differently, or you didn't anticipate it and you should just log&abort.

  • Procedural (unregistered) in reply to PetervF
    PetervF:
    Procedural:
    True about java's stack dump, I don't use java though. It never seems to fit well in the solutions we look for when we look for either speed of execution, speed of iterative development or availability of labour in this area.

    If you're looking for both speed of execution and development speed java and comparable languages are actually a nice middle ground.

    Procedural:
    As for memory, it is exactly likely to crash there. A quick glance at the suggested use of the code suggests that the stability of the app depends on the whole return value (here, a CSV output of a table) to fit into useable memory.

    Which is why just truncating a string is a silly idea. What's the point of an export that may or may not contain all the data requested?

    Procedural:
    If your query is too large, nothing here will protect you. You will run out of memory. A better solution is to write the results to a constrained file buffer that is flushed at regular intervals (ex, integer multiples of the block size of the storage device) and one last time at the end, rather than build it up in one heap or stack variable. Then at least you have more leeway before you need to build code defenses against queries that return too large a data set.

    And you didn't want to use java because of development speed?

    OutputStream out = new BufferedOutputStream(new FileOutputStream(...));
    
    Procedural:
    Disagreement isn't trolling (unless you live in a totalitarian state of something). If you wish to see an example of trolling, pick up any samples of your own writing.

    It's just that it's difficult to believe that you'd consider handling out-of-memory errors in some random function by ignoring (but logging) the problem to be a good idea. Either you anticipated that you might not have enough memory and you should have written your code differently, or you didn't anticipate it and you should just log&abort.

    Agreed; as I said above this isn't a language I use so I was unaware of the difference, while taking a cursory look at the code, between an Error and a RuntimeException. I won't defend the code itself as an example for all to see; I just don't think it is so much of a WTF. I could see people using that for a few runs to test a few things, then perhaps forgetting to remove that quick hack or being moved to another project, or teh consultancy being completed, or whatnot. It certainly isn't great code or a perfect example. I would have done things differently in a language that I master. But I've seen much better CodeSODs before.

  • (cs) in reply to Squire
    Squire:
    Not only does using a StringBuffer yourself result in needless wordiness, it also generates more bytecode. If you use String concatenation over a StringBuilder, it'll be simpler:
    Whoah, hold your horses there squire! I'm not sure you just demonstrated what you think you demonstrated. I'm no JVM expert, but it looks to me like TRWTF is that this much-rehearsed old saw is actually not true in any significant sense:
    Squire:
    public static java.lang.String methodA(java.lang.String);
      Code:
       Stack=2, Locals=3, Args_size=1
       0:	new	#7; //class java/lang/StringBuilder
       3:	dup
       4:	invokespecial	#8; //Method java/lang/StringBuilder."<init>":()V
       7:	astore_1
       8:	bipush	34
       10:	istore_2
       11:	aload_1
       12:	iload_2
       13:	invokevirtual	#9; //Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
       16:	pop
       17:	aload_1
       18:	aload_0
       19:	invokevirtual	#10; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       22:	pop
       23:	aload_1
       24:	iload_2
       25:	invokevirtual	#9; //Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
       28:	pop
       29:	aload_1
       30:	invokevirtual	#11; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       33:	areturn
    public static java.lang.String methodB(java.lang.String);
      Code:
       Stack=2, Locals=1, Args_size=1
       0:	new	#7; //class java/lang/StringBuilder
       3:	dup
       4:	invokespecial	#8; //Method java/lang/StringBuilder."<init>":()V
       7:	bipush	34
       9:	invokevirtual	#9; //Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
       12:	aload_0
       13:	invokevirtual	#10; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       16:	bipush	34
       18:	invokevirtual	#9; //Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
       21:	invokevirtual	#11; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       24:	areturn
    What I see there is that all the heavyweight stuff - the object manipulation with new and dup and the virtual method calls - is exactly the same between the two versions and there's just been a bit of minor optimisation of the trivial stack-manipulation opcodes used to set up the method call arguments. That suggests to me that the difference between the two methods is the kind of fairly small micro-optimisation that you'd only worry about if you were running it millions of times a second. Of course, given that there's no benefit in writing the source in the wordy fashion, that doesn't mean you'd want to go ahead and use this style, but I think it's commonly assumed to be a much worse overhead than it actually in fact is.
  • (cs) in reply to VB Programmer
    VB Programmer:
    Dignissim:
    In all fairness, I do find it kind of counter-intuitive. Why are backslashes too scary for basic?
    Second, vb.net doesn't support the \" escape character as far as I know, you need to use "" to represent a dbl quote in a string.
    Well, yeah, that's the point.

    So you use a double quote as an escape character to escape a double quote. What do you do if you want to escape something else?

  • (cs) in reply to jasmine2501
    jasmine2501:
    Stephen:
    It does not matter. Had he just concatenated the strings, the compiler would have used a StringBuilder anyway.

    Not if it is C# - I'm not convinced this is Java, and if it's C# then string concatenation results in some wonky stuff behind the scenes... it is still crap though.

    So you're saying we'd need to see this "StringBuffer" class and its "append" method before we can judge the WTFness of this code?

  • (cs) in reply to jasmine2501
    jasmine2501:
    I'm not convinced this is Java, and if it's C# then string concatenation results in some wonky stuff behind the scenes...
    If it's C# then it's capitalized all wrong. Unless you assume that someone's written a whole new class library for C# that just happens to use the same capitalization rules as core Java. Could happen I suppose, but "it's Java" is a much simpler assumption to make.
  • Dave (unregistered) in reply to Squire
    Squire:
    Not only does using a StringBuffer yourself result in needless wordiness, it also generates more bytecode. If you use String concatenation over a StringBuilder, it'll be simpler:

    That's what I love about Java, its nice abstractions remove any need for the user to know about low-level details, unlike that nasty C "strcat()".

  • b (unregistered) in reply to OutSource

    I think that's not the misunderstanding. I think the original coder wanted to call the method "insertAStringWhichMightHaveCommasInItIntoTheCSVFile"

    but felt that was too wordy so just called it insertComma.

  • peter (unregistered) in reply to Squire

    What happens when you change methodA to inline?

    I.e.

    return new StringBuilder().append(c).append(s).append(c).toString();

    A lot of the extra bytecode is where it's getting the value of sb for each call, even though it's returned by each append method.

    Although it can be harder to read, method chaining can reduce the bytecode size

  • berry__ (unregistered) in reply to peter
    peter:
    What happens when you change methodA to inline?

    I.e.

    return new StringBuilder().append(c).append(s).append(c).toString();

    A lot of the extra bytecode is where it's getting the value of sb for each call, even though it's returned by each append method.

    Although it can be harder to read, method chaining can reduce the bytecode size

    This: berry@ubuntu:~% cat Foo.java public class Foo { public static void main( String[] args ) { System.out.println( methodA( "foo" ) ); System.out.println( methodB( "foo" ) ); }

        public static String methodA( String str )
        {
                return '"' + str + '"';
        }
    
        public static String methodB( String str )
        {
                return new StringBuilder( ).append( '"' ).append( str ).append( '"' ).toString( );
        }
    

    } berry@ubuntu:~% javac Foo.java berry@ubuntu:~% javap -c Foo > foo-byte-code.txt berry@ubuntu:~% cat foo-byte-code.txt Compiled from "Foo.java" public class Foo extends java.lang.Object{ public Foo(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return

    public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String foo 5: invokestatic #4; //Method methodA:(Ljava/lang/String;)Ljava/lang/String; 8: invokevirtual #5; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 11: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 14: ldc #3; //String foo 16: invokestatic #6; //Method methodB:(Ljava/lang/String;)Ljava/lang/String; 19: invokevirtual #5; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 22: return

    public static java.lang.String methodA(java.lang.String); Code: 0: new #7; //class java/lang/StringBuilder 3: dup 4: invokespecial #8; //Method java/lang/StringBuilder."<init>":()V 7: bipush 34 9: invokevirtual #9; //Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder; 12: aload_0 13: invokevirtual #10; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 16: bipush 34 18: invokevirtual #9; //Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder; 21: invokevirtual #11; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 24: areturn

    public static java.lang.String methodB(java.lang.String); Code: 0: new #7; //class java/lang/StringBuilder 3: dup 4: invokespecial #8; //Method java/lang/StringBuilder."<init>":()V 7: bipush 34 9: invokevirtual #9; //Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder; 12: aload_0 13: invokevirtual #10; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 16: bipush 34 18: invokevirtual #9; //Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder; 21: invokevirtual #11; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 24: areturn

    }

  • (cs) in reply to dkf
    dkf:
    Procedural:
    Anybody who has done database exports and imports of large data sets knows that memory (and memory limitation errors) is a persistently nagging problem. Catching it as it occurs as a quick-hack way of knowing how long your string can be [...]
    But it won't work.

    As with all truly serious problems, Java signals out-of-memory with an Error subclass, not a RuntimeException subclass. That code can't fail in the way you describe. Nor can it fail and hit that exception at all since the delimiter handling won't fail and even a null String won't cause an exception. It's a useless cargo-cultism, a piece of voodoo exception handling that has been waved around some perfectly innocent code in an effort to make the author of it feel a bit better, all to no effect.

    Of course, the most serious WTFs are the things it doesn't do, of which failing to deal with embedded delimiters is the most serious (because it makes the code wrong). I'd suggest telling the culprit about little Bobby Tables, but I really doubt they'd learn the right lesson…

    You'd make Feynman proud ;) Kudos.

    I have relented and added triggering exception handlers as a critically necessary part of the test suite. Not only you need it for code coverage, but -- as you pointed out -- to verify whether you assumptions hold as to an exception being raised in particular circumstances. It seems to me that all code posted on online forums is basically made up in that sense. By "all" I mean more than 99% -- that's "all" enough for me. People just blindly believe whatever they are told, yet checking such things usually requires a few dozen lines of a testcase... If you're a "professional" developer, you should have tools set up to be able to test such things in a couple of minutes.

  • VB Programmer (unregistered) in reply to Watson
    Watson:
    VB Programmer:
    Dignissim:
    In all fairness, I do find it kind of counter-intuitive. Why are backslashes too scary for basic?
    Second, vb.net doesn't support the \" escape character as far as I know, you need to use "" to represent a dbl quote in a string.
    Well, yeah, that's the point.

    So you use a double quote as an escape character to escape a double quote. What do you do if you want to escape something else?

    Like what? For a carriage return and line return I use the vbcrlf keyword. \n is easier, but I don't use vb.net for succinctness. The original point was how VB programmers were afraid of backslashes. We're not, we just don't need them. Regardless, what does the difference in syntax have to do with the intelligence or ability of the programmer.

  • RandomUser423662 (unregistered) in reply to Watson
    Watson:
    VB Programmer:
    Dignissim:
    In all fairness, I do find it kind of counter-intuitive. Why are backslashes too scary for basic?
    Second, vb.net doesn't support the \" escape character as far as I know, you need to use "" to represent a dbl quote in a string.
    Well, yeah, that's the point.

    So you use a double quote as an escape character to escape a double quote. What do you do if you want to escape something else?

    If you are talking about VB.NET, you need only look at the language specification to see that there are only a handful of characters that cause problems for string literals. The double-quote characters (U+0020, U+201C, U+201D), which you can handle by doubling-up, and the line-terminator characters (U+000A, U+000D, U+2028, U+2029), which are admittedly more annoying to deal with. All other Unicode characters are (supposedly) valid within a string literal.

    I can't find a language specification handy for VB6 or earlier, no not sure there.

    It would be nice to have a clean way to deal with the line-terminator characters, and doubling-double-quotes seems a bit hack-y (but that's how it evolved), but otherwise I find myself agreeing with "VB Programmer". For-why do people seem to think VB(.NET) "vitally needs" backslashes for strings?

Leave a comment on “Insert Comma?”

Log In or post as a guest

Replying to comment #:

« Return to Article