- 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
Agreed. There are very few situations where you need more than ten lines in a method (other than naked local variable declarations, for all you 4:3 screen users that put them on separate lines). The only exceptional situation I can think of is when you have to map complexThingA to complexThingB (e.g., anything with XML, OR-Mapping, factory pattern, etc., since you potentially need large switches).
If you have loops more than two or perhaps three deep, it's time for some more classes.
If I'm not doing a complex mapping, I expect each class to fit on one screen (with comments hidden). I tend to combine very closely-related lines of code on the same line to pull this off, such as setting properties from constructor parameters.
Fitting almost all my classes on one screen really helps me "get" each class. But I'm a freak, so YMMV.
Admin
RE mapping between objects: I've done operator overloading (yes, I know it tightly couples the objects) to make the method cleaner, or even a generic helper which caches all the PropertyInfo in a dictionary so you can quickly do it in one place using reflection. This has come in really handy when dealing with DTOs, BOs and view models. If you're not a reflection fan, check out this link. I've done both, and put them in extension methods so you get code like this:
BTW - I believe Jon Skeet (God) originally wrote the PropertyCopy, and other utils like this.Admin
I can identify with this attitude - but only a little.
I've worked with people who like everything on one screen themselves - but they were writing Fortran on a 80x24 screen. No matter how much I encouraged them to progress to the 20th century and utilise the functionality of their VT100 terminal emulator, i.e. expand it to 48, or even (gasp!) 72 lines, nobody took this suggestion on board. The excuse was "It makes it too small and impossible to read." The backatcha "But you're happy reading emails at that resolution, where's the problem?" never seemed to wash.
Some of this may account for the fact that none of these Fortranites were offered the opportunity for training in other languages, e.g. java, c, html, SQL, xsl, jsp, etc. Then they wondered why they faced long-term unemployment when the company had to downsize.
Admin
I kid, I kid, Perl is great! :D
Admin
I do that too, for object => object conversions. Needless to say, it's the appropriate cast operator we're overloading (for the benefit of the audience).
Yeah, you need to cache those PropertyInfos. I swear it's like we share the same brain.
Admin
Admin
Admin
You don't know what you're talking about: people that insist on a single-return statement are stubborn and narrow-minded. In addition, it's easy to create logical errors with single-return statement in [longer] functions.
Admin
On the contrary, idiots write single-line if-content on the same line as the if. It's unreadable, and my mind first catches that "c.cleanup" to be what executes if that test returns false.
Admin
I spotted that one too, but I can't always think of how to squeeze something out of it. When you've been deep in this business for as long as I have, you get tired of picking all the low-hanging fruit.
Anyways, I'm thinking of moving on. I'm thinking of starting a web comic that takes a hard look at current events. It'll have a cast of creative and thoughtful underdogs that rail against the injustice that pervades modern society. Maybe a strip will consist of our heroes at the NYSE giving out random hugs in order to engender caring for one's fellow man ("Gold... is cold, man!"). And then they all fuck each other.
Admin
Admin
For that matter, I often do this:
foreach(blah in blahSet) if (blah != null) blah.blegh();
Which is just as clear as the 6-7 line version you would have, but I also get to see the entire class on the screen, which is VERY readable.
Addendum (2011-08-12 12:41):
But I'm just as likely to do:
Admin
I'm going to have to strongly disagree with you about the first one because there's no "cue" for the readers eyes of where the code flows. Sure it makes sense to you because you wrote it. That being said, I like your second example because at least it groups each expression visually, though if it got one more level complex (i.e. ToArray()), I'd break it into seperate lines. An if without brackets is fine, but I still prefer to break it into two lines, except in the case of a short lambda.
Just a quick question: do you shorten method and/or variable names to minimize screen usage?
Admin
Addendum (2011-08-12 14:18): I wonder how you feel about this - taken from something I'm writing right now:
[code]query.Result.Where<Order>(o => o.ShippedOn.Date == DateTime.Now.PriorDay()).ForEach<Order>(o => { /do stuff/ });
Admin
Admin
Admin
Admin
Admin
Admin
So, never start a sentence with a "goto", unless you're an experienced writer. Got it.
Car analogy: Hands at 10 and 2 (or 9 and 3, or whatever the hell they're teaching nowadays).
Admin
int doSomething(int param1, int param2) { //blah if x() return 1; //blah return 2 }
then you need to log or run something after function end, you can do
int doSomething(int param1, int param2) { int r = doSomethingCore(param1,param2) doAnotherThing(param1, param2); return r; }
int doSomethingCore(int param1, int param2) { //blah if x() return 1; //blah return 2 }
Admin
Cool, using very long parameter names, you dont ever need to comment the code, put the comment in name of things.
Admin
Like the man who preferred to communicate with the departed by means of a contented psychic, I prefer a happy medium.
What about names that are long enough to communicate intent, but not so long that they have to be parsed. longSentencesWithoutSpacesOrPunctuationEvenIfTheyHaveInternalCapitalizationAreHardToReadDontYouThink = true.
single-letter variables are fine for loop counters, anything else should be a word or two. If you need more than that, again, your method may be too complex.
Admin
You're a fucking pervert. But then you already know that. Yum.
Admin
a) The instance parameter in an extension method, b) The only parameter in a private method, c) The only type parameter in a generic method/class, d) Lambdas, e) Truly open data format abbreviations like CSV and XML, but not DOC, XLS, JAR, et cetera. Not TXT because it's one extra letter to spell it out, f) Vernacular abbreviations like ID, g) When I've already used, in scope, the most appropriate variable name for a type, and I need a second one because I'm juggling or cache-swapping or something, I abbreviate the second variable, h) Event signatures (obviously).
Unless a variable is absolutely private (not internal or protected), I also give it XML comments.
Other than that, I follow every guideline recommended by Microsoft, from capitalization styles to asynchronous API design. Except I also prefix fields with , which is not really an MS recommendation but is pretty standard (that or m).
I spend a hell of a lot of time coding to the API to make sure whoever comes behind me has an easy time. I'm not going to throw it all away on lazy/bad/proprietary style.
Admin
Admin
So to my mind, this:
Is no more complex than this:
And it doesn't matter who writes it. You can nest the foreach down to infinity and, as long as the ifs are only null checks, I won't ever get lost.
I think it has to do with all the DBA stuff I do. I am terribly used to conditional set-based operations like this:
Which has precisely as much complexity as:
Admin
TRWTF is.... um, actually, no, that's pretty good. Carry on.
Admin
Single point of return isn't the problem. Assuming you must do things procedurally, sounds like code that should be decomposed into multiple functions. The function you're describing sounds monolithic, suffering from the lack of a clearly defined responsibility (see Single Responsibility Principle). Or poor design in general.
Admin
As I'm catching up on a few days of codeSOD, I read this comment and want to shout out: "Thanks for pointing this out!" Full ACK.
Admin
And remember, prepositions are something you never end a sentence with.
Admin
I'm sure you have that backwards. RET does not take parameters, so it should use fewer bytes than JMP.
When the last thing a subroutine did was to call another subroutine, then you could save bytes and cycles by using JUMP instead of CALL followed by RET.
Admin
Yes you can... you just have to make copies of the string, thereby making the code even worse, and it wouldn't even look all that different.
Admin
No it isn't, at least not on most platforms, in C return is implemented in whatever way makes sense for the ABI, and often that means drop the return value in a specific register and execute the 'ret' instruction. (There may also need to be stuff to restore callee saved registers that have been used, and possibly restoring the old stack pointer and frame pointer if the ret instruction doesn't do that and they have changed).
Also why would it be sad? It makes sense if the function epilog is long since it results in smaller code, in any case as a C programmer you don't need to care.
Admin
C is decidedly not one of those languages
Admin
Except frequently that stack unwinding code isn't terribly fast because the assumption is that it doesn't run very often, and it may need to do quite a bit of work to figure out what stuff it actually needs to clean up since optimization tends to obscure that sort of information. Since you are making assumptions about what optimizations exist anyway you might as well assume the compiler can do a tail call optimization and write your function to be easy to analyze for that, you'll get clearer code.
Admin