- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Oh no! The ? : operator! It is confusing and I am frightened of it! It is the real WTF!
Admin
I see someone took the string literal advice a little too literally.
Admin
I think my favourite is the usage of a COMMA constant and a "." string literal. Despite this engineer's obsession with constants, they appear less concerned with consistency!
Admin
I nearly shat myself laughing at the first one! And then I did when I saw the second. OMG, that was insanely funny!
Gotto go change underpants, excuse me [:D]
Admin
A few comments:
1. These are actually part of the same code. The second part uses the constants from the first part.
2. Alex cleaned up the formatting. There were no indentations.
3. Using StringBuffer as shown in the second part actually performs worse than using the + operator because the compiler inlines the literal concatenations, even in local declarations.
4. I posted this because it made me laugh so hard when I saw it during bug hunting. It's actually not the worst offender.
Admin
Well, obviously COMMA and EQUALS might change in SQL syntax. '.' cannot. Duh!
Admin
Can't you all see the brilliance in this? If the SQL standards ever change, and you can no longer use commas to delimit column names in SELECT statements, this application is all set! It will be one of only a handful of applications to still work in this new, golden, comma-less age.
Admin
Gotta go clean out the brain now. It has been filled with vile code. Be back in a few years. [:D]
Admin
Now, let us not gloss over the bit:
He's using StringBuffer.append to avoid concatenating strings, and yet, does it anyway, right in the middle of the append!
Admin
Ok now that's out of the way...I have only one thing to say...in response to the ?: comment. I believe that the ?: operator does have a good and worthwhile use, but this WTF is not it.
On another side note, the way the second example is formatted reminds of the blocks of ASP/PHP/Perl code consisting of
$var .= "foo";
In those languages, Heredoc strings are your friend.Admin
Magnificent...how would you even come up with something like that?!?[:|] The mind reels...
Admin
It could have been worse... he/she could have thrown in a few string.format("%s"...) for fun ... and maybe do some lookups in a string table...
Admin
In my early programming days (and sometimes even now), I wrote my fair share of amazing WTF code, and I've run across some pretty scary WTFs from newbies and experienced programmers alike, but I simply cannot believe this first code example was taken from production code. The thought process behind this code is unfathomable to me. I wouldn't have been able to get through typing one line of this without realizing that something was seriously amiss with this methodology.
I hope for the sake of humanity that this code is a fake.
Admin
I stumbled across this site only a few weeks ago, but I've been reading the Daily WTF every day since then. I've seen some questionable things, and I've seen some boneheaded things, but this...
Code like this makes the baby Knuth cry. :'(
If this isn't a joke I'd fire the incompetent putz; either that or I'd attach a hose to their ear and take over the home vacuum market.
Unreal.
Admin
I'm no StringBuffer() expert... could someone explain what is "wtf" about the second portion of the code?
Admin
I wish it was fake too. This query (or something like it) was taking about 3-5 hours to execute. It took forever just to figure out what it was doing. Even after we grabbed it from the logs, we still were trying to figure it out. The funny thing was that it had a nested query 'select [email protected] from ...' in it. I don't know if he wrote it, but he was the CTO at one point.
Anyway once we figured out the point, we added an extra where and it runs in 5 minutes. But what a waste of time.
Admin
When you do this in Java:
String s = "start" + "finish";
It compiles into the equivalent of:
String s = "startfinish";
In other words, the + doesn't do anything at runtime. This is true for any literal (constant, etc.) that can be determined at compile time.
By forcing the StringBuffer concatenation, you force this concatenation to happen at runtime. So not only is the code harder to read, it's slower.
The other thing is that in any version of Java > 1.3, + for no-literals will compile into the equivalent of the StringBuffer append (or StringBuilder in 1.5) version anyway.
You should only use StringBuffer when you are repeatedly adding Strings to each other in a loop or similar operation where the entire concatenation can't happen at once.
Admin
Don't know about Java, but in .Net the String object is immutable which means anytime you try to add to it, behind the scenes, an extra copy of the object is created - and the original value and the new part are then added to the new object
not such a big deal with a simple couple of concatenations, but when u have some repetitive load of concats, it is more sensible to use a StringBuilder object, (and its Append method) which is not immutable (mutable?? :) - u dont get lots of extra objects being created - hence conserves memory.
Admin
Admin
The compiler will use StringBuffer for non-literal concatenations anyway, and a lot of these concatenations are literal so the effect is multiplying the number of runtime concatenations and making the code harder to read.
Admin
This is true in Java as well.
Both will also concatenate the strings at compile time if they are literals and constants.
Admin
Which only means he should have used a PreparedStatement, which is:
Admin
C# is basically, at it's core, a clone of Java so a lot of these things are the same. I assume the C# does what Java does i.e. turn:
String s = a + b + c;
into the equivalent of:
s = new StringBuffer(a).append(b).append(c);
There is no benefit to doing this manually. Even in the old versions of Java that used the String.concat() method, you need to concatenat at least 3 Strings before you see any benefit at all. To see a noticeable benefit, you'd need to concatenat dozens.
Admin
In the above, a, b, and c are non-literal Strings.
Admin
Quick question(s) from a java newbie...
If say all of these variables were constant strings, wouldn't the compiler just squash them together into one big string instead of calling append over and over again?
However, I get the feeling that these variables aren't constant...
I also ask myself why this stuff isn't put into a class that builds SQL statements for you...
Thanks!
Admin
The Java convention is to make constants all uppercase and this code follows that convention.
COMMA and OPEN_PARENTHESES are not dynamic values.
Admin
Same thing happens in Java. However, the compiler is smart enough to reuse the StringBuffer it builds behind the scenes.
String foo = bar[0] + bar[1] + bar[2] + bar[3] + bar[4] + bar[5] + bar[ 6] + bar[7]; // uses one StringBuffer.
String foo = "";
for (String barValue : bar) {
foo = foo + barValue; // one StringBuffer per time around the loop.
}
The only exception is when the array or collection is bounded at compile time; in this case the compiler may unroll the loop and use just one.
Admin
Naah. Believe it or not, C# is a clone of Delphi, with C syntax bolted on. Don't be fooled; you get a considerably greater insight into the language if you get away from the whole "Microsoft hates Sun" concept as early as possible.
Admin
I remember a WTF posted here (?or elsewhere) that went like
const ONE = 1
const TWO = 2
const THREE = 3
and so on...
Even if SQL dispenses with the comma and uses, say, the caret (^) character instead, I'm sure the guy above will make a
const CARET = "^" instead of the "advantageous" const COMMA = "^" change.
Admin
So explain how it is different from Java or are you saying that Java is a clone of Delphi with C syntax?
Admin
Think of it like this: the Cylons build a human being called "Boomer". She looks like a normal person, but she's really a Cylon. There are differences, of course: presumably she's "better... faster... stronger...", which is a Cylon trait rather than a human one. And she has a tendency to do evil things when no one is looking, which is also a Cylon trait. But she looks human, and that fools people into thinking she is human.
Similarly, Anders Hejlsberg, the main architect of Turbo Pascal and Delphi, built a language called "C#". It looks like Java, but it's really Delphi. It's got a bunch of differences from Java (go check the doco if you need to know what they are). As with the lovely Boomer, C# is in disguise, and people are fooled. But the philosophy of the languages is very very similar; you'd expect that, since Anders probably jumped ship from Borland to Microsoft just so he could do what he loved - creating good languages - without the marketron bullshit that constitutes Borland's entire strategy and mindset.
That's why C# doesn't have the horrible straitjacket feel of Java, and why it just works so much better. It's a better, faster, stronger language, in disguise purely for political reasons.
You are welcome, of course, to believe otherwise. You'd be in good company - at least until things get explosive. Ask Commander Adama about that, if you like.
So say we all!
Admin
By the way... here is a comparison of C# and Java from a Javanaut's perspective. Interesting to note that nearly all the things in the "wish you were here" section - the things that exist in Java and not in C# - are things I consider evil and wrong-headed about Java: class nesting, checked exceptions, the failed attempt to make it Write Once and Run Anywhere, and so on.
(BTW I had to use the HTML editing pane to put that link in. This forum software is still seriously unhealthy, though it's improving.)
Admin
Heheheh.. I've seen kinda similar code before - in an effort to free decouple a particular piece of code from the database, the guy had used constants for all the column/table names eg:
<font size="2">
</font><font size="2">"SELECT "
TBL_NAME_PARTICIPANTS + "." + FLD_NAME_DESCRIPTION +
" FROM " + TBL_NAME_PLAYERS + ", " + TBL_NAME_PARTICIPANTS + " WHERE " +
TBL_NAME_PLAYERS + "." + FLD_NAME_ACTIVEYN + "= 1 AND " +
TBL_NAME_PLAYERS + "." + FLD_NAME_TEAMID + "= ? AND " +
TBL_NAME_PLAYERS + "." + FLD_NAME_PARTICIPANTID + "=" +
TBL_NAME_PARTICIPANTS + "." + FLD_NAME_ID;</font>
Impossible to read... thank God for search and replace!
Definitely PreparedStatements would be the way to go. Often people do this sort of thing when they've been told that they mustn't tie themselves to one database - a flexibility almost never used, and better done by creating a data access layer instead. That way you can unplug and replace it should you ever decide to change.
Admin
I don't think that's bad practice at all. If you format it properly it looks just like any other SQL. The nice thing is about that is that you can use the constants to retrieve the values from the resultset. You can avoid a lot of errors this way and if the column names have to be changed for any reason (it happens), you don't have to make the update in two (or more places).
Also, the above appears to be a PreparedStatement. Perhaps you mean 'stored procedure'? I'm a fan of those too.
I don't find this:
"select " + BLAH + " from blah "
+ "where " + FOO + " = ?"
difficult to read at all. Maybe it's not neccesary but I don't think it's a problem.
Admin
True - if the names are BLAH, or FOO then they're not so bad - I think it was prefixing everything with TBL_NAME or FLD_NAME that made it such a trial for me to read..
But then, I don't really like the idea of using BLAH or FOO for constants, as it gives you no clue what they really are - unless you put them in an interface TableNames - in which case you should really refer to them as TableNames.FOO - which makes it nasty to read again :S
Hmmm - argued myself back to the beginning.
I suppose I think it would depend on how likely table name changes are
Although, pondering more, even if table/column names were likely to change, I'd prefer to either use external SQL files (so you can change them without re-compiling, and run some verification over them to check for incorrect tablenames) or the Store approach, where all the database access is in a small number of classes so you know where to look. To each their own I suppose.
Admin
I find that site backs up my assertion that C# is basically a clone of Java. A lot of the features that are in C# but not in Java are, in my opinion, either abominations or silly syntactic sugar that makes code opaque.
C# has nested classes, at least according to that page. Just no anonymous classes which are extremely useful when weiled carefully. Checked exceptions make perfect sense to me. If you have something that the caller must handle why not make it obvious? Isn't the invisiblity of exceptions the big gripe about them? As far as write-once run-anywhere, it may not be reality but it's close. I do all my development, builds and unit testing in Windows and deploy to Unix. Works perfectly. If there's a Java version of a piece of software available, I've always been able to run it in Linux.
On a side note, that page is out of date because some of the features have been added to Java in 1.5. It goes both ways. C# steals from Java, Java steals from C#. I don't think it makes MS evil or vice versa, it's just pretty clear both languages are similar. The only thing that strikes me as humorous about it is that a lot of hard-core softies were adamanat that running on VM were bad and slow and then MS creates a language that runs on a VM and those same people sing the praises of VMs.
Admin
The constant would be the same as the column name like:
String sql = "select " + FNAME + ", " + LNAME + " from employee"
I think that using interfaces for importing constants is very bad practice. If you go to the Java forums and search on that subject you'll find lots of discussion about why. If you put the constants in the class and name them properly, there should be no confusion.
Actually, I find this technique most useful during development. There's nothing worse than finding out at the last minute that you need to add a join with common columns or have to predend a user name to the beginning of the table names. I suppose you can make the argument that this can be dealt with in other ways.
I do agree that for 'static' SQL, stored procedures are good, although that means a lot more interaction with the DBA, which may or may not be a good thing.
Admin
Hmmm.. not convinced - I'll have to read the discussions when I get a mo - I can see why it's nicer to put them on the relevant class rather than a separate interface, but if like in much of the code with which I'm working at the moment, different classes have to reference the same table/column. How do you deal with that? Declare the same constant in more than one class (thus losing the easy update if column names change) or refer to it on the other class (losing readability)?
Feel free to tell me to just read the forum if you want :)
Yes - I think I was just agreeing with someone further up, that PreparedStatements are a better idea than appending in the variables. I like stored procedures for things that need to be fast, but as a rule I stick to keeping SQL application side - DBAs get a bit too territorial :P
Admin
I've been reading this forum for a couple of weeks now, but this looks to me like a WTF... why would you prepend table names with user names? Needless to say most people would deal with that in other ways. (see that Database of Databases wtf)
Admin
Can't think of why you'd prepend usernames - but view and schema names certainly.. typo?
Admin
Schema is what I mean, I think in an old DB I used it was called 'user' name.
Admin
Exactly... I don't like the article itself, though it has valid points, I didnt like the way the author approached it (C# > Java).
Java 1.5 improved a lot, and most of the critics aren't true anymore as you mentioned, but it also added other improvements (i.e. generic-types - a'la templates in C++) which C# doesn't have.
There are plenty of things that I dislike about C#, the unchecked exceptions is one, the ugly attributes per object/method/... The syntax for extending and implementing that doesn't make a clear destinction between the 2, passing variables by reference - which is bad coding practice imho :) And if you really really need to pass a base-type by reference, box it - class instances are always passed by reference... Also I don't like the article's author example of swapping 2 values :) He uses 1 var too many, who the hell needs an extra var when swapping 2 numeric var's?? This still works (in C/C#/Java/C++/...): [:D]
int var1 = 10;
int var2 = 123;
// Swap them using XOR'ing :)
var1 ^= var2;
var2 ^= var1;
var1 ^= var2;
// Et voila - swapped them - that wasn't too hard now was it? :)
VB coders are prolly scratching their head now - but well (soz couldn't resist [:P])
Anyway - both languages have their advantages and disadvanteges, it's a matter of taste, but I think both are equal, though Java has the advantage of being more mature, and having more features in it's standard framework.
Admin
I guess the idea is that when you import the constants from an interface, they seem to come out of thin air. If you have a lot of classes in the heirarchy it can be hard to find where they come from. Also, interfaces are subject to the problems with mutliple inheritance. If you import two interfaces that both declare a NAME constant, which one does the compiler use?
The problem you mention with using the class name to qualify the constant is exactly why 1.5 introduced the static import feature (this is what I understand, I have not used it.)
Admin
WTF, why not put the SQL in a managed properties file? Do you really have constants for SQL grammar?:
public static final String SELECT = "SELECT";
public static final String ALL = "*";
public static final String FROM = "FROM";
and end up with stuff like:
SELECT+SPACE+ALL+SPACE+FROM+....
Thats not a WTF?, thats an OMFG, WTF!?
Put sql in prop files, hide them behind factories for more insulation/configurability.
Admin
Eugh.. I hate the idea of the static imports..
I realise that in my pretty IDE I can just right click on the name and find where the constant came from but I still find the idea of just using the name, without saying where it's from icky.
Oh, yes, multiple inheritance.. of course! That's an excellent reason for not using interfaces as constant repository.
Admin
Oh Koffie - EXCELLENT! Love the number swap :)
Admin
OH + DOT + MY + DOT + GOD + EXCLAMATIONMARK;
Admin
But isn't that exactly what you are doing when you use an interface to import the constants? At least with the static import there's a little visibility. I can see how it would be bad in most situations but I think it's useful in a few special ones.
As far as using constants for the column names, perhaps it's a WTF. I like knowing that the name I call the SQL with will always be the same thing I retrieve the value with, guaranteed. Maybe it's overkill. I'm tend have a lot of what my gramar school teachers called "careless errors" so I do a lot of these things to save myself from myself.
Admin
C# version 2.0 has generics.
Admin
I don't know why it says I wrote that because I did not.