When you join a team, it's important to bend your preferences a little to accommodate the generally accepted coding practices of that team. Not everyone has to agree on every miniscule detail of the code, of course, but it's a good idea to dicuss it with your team and decide on overall approaches and philosophy beforehand. It promotes team harmony, and more than that, it's just common courtesy. As they say, when in Rome, do as the Romans do.
I've always been wary of cowboy coders who rolled into an ongoing project on fresh horses and immediately started dictating terms. It's a very short trip indeed from there to Who Wrote This Crap, and the predictable, inevitable finger-pointing at the foolhardy programmers who came before you begins. Don't be that guy or gal. Work with your team, not against it.
Still, there are some coding preferences people may feel.. strongly.. about. If that's the case, try to clear the air and address those strong preferences up front, as early as possible. Don't let them simmer. For me, the use of #region is one of those things. I tried to make myself clear in this twitter message:
So what is #region? It's a named hint you place in C# or VB.NET code to set a code folding point. Any code placed inside that region is, by default, collapsed when you re-open it in the editor. Here's a random example from the Log4Net project:
Immediately I have a problem: I can't see anything! I have to manually expand those sections to browse any of the code in this class. It is possible to configure the Visual Studio IDE to not fold any of the regions when files are opened, but this is the out of box behavior, so that's what most developers will see. And of course there are keyboard shortcuts to deal with the regions:
| Ctrl+M, Ctrl+M | Collapse or expand the block you're currently in. |
| Ctrl+M, Ctrl+O | Collapse all blocks in the file |
| Ctrl+M, Ctrl+L | Expand all blocks in the file |
| Ctrl+M, Ctrl+P | Stop outlining mode. (Ctrl+M, Ctrl+O resumes) |
Here's the really sick part: once you expand the above log4net code there's literally three pages worth of code there! After you strip out all the massive XMLDoc comments and the dozen or so #region directives, you could have had all the code at your fingertips with a minor flick of the mouse wheel, in a simple scrollable layout.
I daresay being able to see the damn code is more important than having it meticulously segmented into six pointless little named buckets, but apparently a lot of programmers can't get enough of stuffing their code into pointless little named buckets. It's as if they've forgotten what the scroll bar -- and incremental search -- is for.
The #region directive drives me bonkers. It's not evil, per se, but I feel it is criminally overused in practice and heavily prone to abuse. I strongly urge you to think about how you're using code folding, because as I see it, there are a lot of downsides:
#region has zero meaning to the compiler; it's a hint to the editor to allow code folding. It doesn't do any namespacing or scoping. Why, exactly, are we writing code to accommodate the editor? It boggles my mind that we'd add significant lines of code to our project that do nothing but offer organizational hints to the editor. Even traditional comments are a better value for your keystroke, because they can be more expressive. And folding is certainly no substitute at all for bona-fide refactoring.
I urge developers to write code that doesn't need folding to be readable, clear, and concise. I'm sure there are sane uses for code folding out there somewhere, but I rarely see them.
Used correctly, code folding HELPS you see code. In this scenario, it hides those three ugly pages of logging code so that you can see the code that matters. If you want to see everything, it's an easy Ctrl+M, Ctrl+L.
JS on July 7, 2008 8:19 AMJeff,
100% agree. #regions blow.
Might as well have called it
#rugwithdustunderneath
#loadedgun
#tomaximizeyourcodingtimeandeffortlookherelast
It is possible to configure the Visual Studio IDE to not fold any of the regions when files are opened, but this is the out of box behavior, so that's what most developers will see.
Well there you have it then. You set up your VS like that and you start working. There, wasn't that easy?
Mike on July 7, 2008 8:23 AMThe worst thing about #region to me has nothing to do with whether or not code-folding is a Good Thing or a Bad Thing. It's that it breaks a mental convention that I'm used to seeing in curly-brace languages, which is that lines beginning with a hash invoke some sort of compiler magic. (Think #include, #if, and others from the bad old days of preprocessors).
The first time I looked at C# code with #region in it, I didn't know what to make of it, it actually disrupted my original task while I went off on a 20 minute tangent of reading docs to assure myself that it didn't in fact invoke some sort of compiler magic. I use Vim, by the way, and it's configured not to fold anything unless I explicitly ask it to.
This is rediculous to me. As far as I can tell, #region is completely ignored by C# compilers, yet there is already a syntax for making the compiler ignore things: it's called a comment. I can't find anyone who can give a compelling argument why a different syntax is needed for *this particular* compiler-ignored directive.
We regularly write comments designed to be parsed by IDEs, documentation tools, and even static analysis tools (vis SPARK Ada's formal verification mini-language). Why is code folding special in the VS universe? Numerous full-featured editors such as Vim have no trouble folding code on commented directives (or on other tokens of the language for that matter), and the commented syntax makes it instantly obvious to people using editors without direct folding support that the directive is semantically inert with respect to how the code will compile and run.
This discrepancy put a bad taste in my mouth for #region automatically, regardless of it's other merits. On the infrequent occasions I put fold markers in my C# code, I usually end up writing // {{{ Vim-style markers just so I don't have to be mentally jarred by seeing something that years of curly-brace languages have trained me to think of as a compiler directive, but which is actually isn't.
Kyle S on July 7, 2008 8:23 AMHeh. I haven't used .NET stuff before. I have to say that I don't find it a good sign when a laguage has a Jedi-mind trick primitive.
These are not the lines of code you are looking for. (*waves hand*) They can go about their business. (*waves hand*) Move along.
T.E.D. on July 7, 2008 8:26 AMIt boggles my mind that we'd add significant lines of code to our project that do nothing but offer organizational hints to the editor.
Spoken like a true zealot. If the amount is significant, than you must have 10 lines of code overall.
Mike on July 7, 2008 8:27 AMThe editor should automatically offer to fold up these common structural blocks for you!
Whaa? So folding IS good?
I have found 3 problems in your argument, and I must come to the conclusion that you are writing this for the views. Well, you have to make a living so do what you feel you need to do, but you are out of my rss reader sir.
Mike on July 7, 2008 8:30 AMHaving to actually put something in your code to support folding sounds brain-dead to me. I use TextMate, and it handles folding automatically, at various levels. I use it mostly with specs, since I often want to see the specs rather than the code that verifies them.
i.e.
describe MyClass do
it should do something do
(...folded)
it should do something else do
(...folded)
describe when doing something do
it should keep track of foos do
end
describe when not doing something do
(...folded)
end
And it is nice that it remembers exactly how I had the code folded when I last closed the file, without me having to insert a bunch of stuff into my source code.
Matt V on July 7, 2008 8:30 AMCode folding is a useful feature. It was bad enough having to strum my mouse wheel 20 times to get to this input box... (please do something about that :) ) doing it in a code editor when I'm trying to remember complicated constructs is worse. Take me, quickly, to the source I want, and then don't confuse me with lots of clutter I don't want to see.
Boilerplate code is stuff we never edit, so we don't need to look at it.
There's a lot of things Visual Studio could do better if Microsoft bothered to copy the competition...
And there's a lot of things they've done very very Right.
Go use Eclipse, XCode or KDEvelop ;)
James on July 7, 2008 8:31 AMAutomatic folding? Use VIM. :)
Bruno Nery on July 7, 2008 8:31 AMI fail to see the problem. You say that you can configure your IDE to expand all by default, so why not just setting this one option and live happy? If other programmers prefer to have these collapsed, why forcing your way upon them if there's an easy way to workaround it?
Mecki on July 7, 2008 8:35 AMFirst of all a lot of people are getting the impression that the only way the VS IDE will do code folding is with regions. This is not the case and the post is inappropriately titled because Jeff seems to only have a problem with the region directive.
Frankly its an opinion not fact. If you don't want to use regions you don't have to, if I want to use regions I will whether or not Jeff Atwood likes them.
Matt Newman on July 7, 2008 8:44 AMIf learning to live with #regions in Visual Studio, I recommend changing the background colour for preprocessor directives. This makes #region markers stand out well as you scroll past them.
I also strongly recommend getting a mouse with a flywheel-style scroll wheel. I got a Logitech VX Nano for my laptop and now I use it with my desktop whenever I can. It makes it much easier to scroll through long source files or other documents. With a flick you can send the wheel spinning to scroll quickly through even very long files, while you still have fine control when you need it.
Weeble on July 7, 2008 8:45 AM#region has zero meaning to the compiler; it's a hint to the editor to allow code folding. It doesn't do any namespacing or scoping. Why, exactly, are we writing code to accommodate the editor?
I *strongly* agree. And in the same way: type declarations add zero meaning to the program logic; it's a hint to the compiler. Why exactly are we writing code to accomodate the compiler that adds nothing to the program (except to prevent you doing all sorts of stuff...).
Michael Foord on July 7, 2008 8:57 AMThe suggestion to simplify one's code by splitting it into to several partial classes is laughable. Partial classes came about purely as a result of the way Visual Studio's form designer works. Otherwise they're a terrible idea IMHO.
PS. Visual Studio doesn't require having to actually put something in your code to support folding.
Rhywun on July 7, 2008 8:58 AMWhere do you see the difference between folding and using different files for different classes ? Both hides lots of codes behind short identifiers, so you don't always have to look at everything at once.
Also: you are welcome to set your IDE to auto expand. Bam!, problem solved for you. You will never ever be bugged by those hidden pieces of code again. Other people on your team, however, do not have an easy way to fold the code away if they wish to do so and you removed all the #region's. Clearly, no #region's hurt part of the team, and lots of #regions don't really hurt anyone (since you can just set your IDE to auto expand if you don't like them). The choice is absolutely obvious.
J. Stoever on July 7, 2008 8:58 AMJeff, you've been reading my blog again!
No to #region
http://mikehadlow.blogspot.com/2006/10/no-to-region.html
Hmm... I have the answer, never use C#. There is no reason for it to exist. As for regions in VB, well VB is so verbose you need regions just to find your code.
I must admit to being a Java coder, so I have biases. I will have to say that I wish that Java had an answer to VS2008. Eclipse sucks, NetBeans makes the programmer code the way it wants you to code, and JBuilder's libraries are out of date. So while MS languages are horrid, their IDE is still better than anyone else. Go TextPad.
Ctrl-M Ctrl-P
What are you, George Jetson? Waaah, Jane, my fingers hurt from pressing 2 buttons.
Or just turn it off in your IDE.
Seriously, call the Wahbulance.
Everyone thinks differently and I'm sure it really helps other people have a framework to get organized. Do I think people should group methods by private and public? No. But I'm not going to write a whiny blog post about it. (I just hit Ctrl-M Ctrl-P and it all goes away...)
And it beats the heck off 100 separate partial class files. Yuck! And there's no way for people that don't like that to fix it.
PRMan on July 7, 2008 9:07 AMWhat's so great about not organizing your code? I mean, I want my programming job to be easier, faster and keep me as much as possible from making stupid mistakes.
Also, there are reasons for being nice to the editor. In fact, I think being editor-friendly is a FEATURE of a language. For example, in C++ it's often hard to figure out where an actual ERROR is, because of an unclosed quote and the semicolons might be all messed up for a long time down. But if line breaks ALSO end a statement, your development time will be quicker over time.
Gregory Magarshak on July 7, 2008 9:07 AMHoly cow. Talk about short sighted.
You don't organize code? Really? You don't place functions and procedures together that all relate in your source files?
Folding has a place and I'm very surprised that you don't see that.
There are a lot of times that we have HAD to use that #Region just so that we can easily find things. You try searching a large file for a word that gets repeated 50 times throughout the whole class file... As soon as we started using #Regions properly, life was MUCH easier and WAY more efficient.
Aaron on July 7, 2008 9:07 AMI'll agree with the other folks here, regions are awsome. Sure, they can be overused (regions within regions within regions). Normally when I open a class, I want to go to a specific part of it. It is rare that I want to see properties and private fields, but when I do typically I don't want to see the methods. And it is only once in a very long time I want to see my references.
Regions make it so that is handled pretty elegantly.
Matt Briggs on July 7, 2008 9:08 AMI think Jeff is wrong on this one. #region is very handy.
In addition, the IDE will fold code on any block level statement, not just regions.
Here is the problem with regions.
When I open up a file in VS, I usually want to see collapsed code, like this:
public string AddressLine1[...]
public string AddressLine2[...]
etc.
I have keyboard shortcuts for the various outlining commands: Alt-Right to expand/collapse all, Alt-Left to CollapseToDefinitions, and Alt-Down to toggle outlining open/closed for the block I'm in.
But regions completely screw up outlining. If I expand everything, I get this:
#region Properties
public string AddressLine1
{
get { return addressLine1; }
set { addressLine1 = value; }
}
public string AddressLine2
{
get { return addressLine2; }
set { addressLine2 = value; }
}
etc.
Too verbose. Whereas if I collapse to definitions, I get this:
Properties
Now I can't see anything. So to get a collapsed view of all the code, I have to collapse everything, then individually open each region, which is an annoying waste of time.
It's easy enough to group things in terms of methods, event handlers, properties, etc. with comments. We don't need to use regions to do it.
Regions should only be used for boilerplate code that doesn't ordinarily need to be seen. Designer code is one example of this. C# event declarations (as someone referred to above) is potentially another. Any code that regularly needs to be edited, or that one needs to be aware of when adding to a class, should not be in regions.
Kyralessa on July 7, 2008 9:13 AMThis is too funny --- I often find myself reading Jeff's stuff and trying to decide if he's right and I'm just old and crotchety about the way code should be (80 char width, hungarian notation, intellisense is the crutch of the weak, etc.) ... today I got to see Jeff turn the corner into old and crotchety too.
Hey you kids, get out of my yard!
---S
If you don't like using #region then don't use it. It's purely a personal preference thing. What I hate is empty regions. You end up clicking on all these regions trying to find the method you need.
Steven Rogers on July 7, 2008 9:15 AM'Folding can hide deficiencies in your editor. The presence of so-called standard boilerplate regions like Public Constructors and Public Properties and Events is not a feature. It's a bug. The editor should automatically offer to fold up these common structural blocks for you! I'm continually amazed that programmers spend time doing this scutwork when they could be writing useful code. Or at least demanding a smarter code editor.'
Folding can hide deficiencies in your editor, while your editor can hide deficiencies in your *language*. I am frequently annoyed when C# (or C++, or Java) requires lots of ugly boilerplate code. Any time I find myself writing the same pattern of code several times I start looking for ways to avoid the duplication, but often I get to a point where it comes down to fundamental limits of the language. Perhaps I would be happier writing Lisp.
Weeble on July 7, 2008 9:15 AM@James:
It was bad enough having to strum my mouse wheel 20 times to get to this input box... (please do something about that :) )
I fixed this problem for you. Next time you want to jump right to the input box, just press the 'End' key. You might have to clear your browser cache for this fix to get downloaded to your machine.
stevey on July 7, 2008 9:15 AM There are a lot of times that we have HAD to use that #Region just
so that we can easily find things. You try searching a large file
I don't have your code in front of me so I can't really make any judgements. However, I've found over the years that if a file gets really large, tough to navigate around, and/or tough to read, it almost always needs some funtionality split out of it and put into another file/class.
My suggestion for users of this #Region thingy would be to instead physically take that code you want to hide out and put it somewhere else.
T.E.D. on July 7, 2008 9:17 AMI think it's overuse that drives people mad not specific use. I often write stuff that uses crystal reports so can have 10 to 15 buttons on screen usually in a tab page each to run a separate report, they all have pretty standard code behind (not the same I couldn't wrap it into a call to a function or anything) and I hardly ever need to see it so I prefer to put it in a crystal reports button handler region. That means my core code is left visible the bit I know is correct is left alone. I don't think many people would object to that.
Over/Misuse is constructors, methods, helper methods, properties, fields... I often think people who do the regions this way are maybe missing the objective of the region it's not to separate your properties from your methods most of the time you need them both on screen.
pete on July 7, 2008 9:23 AMScanning code took too long for me so now i use the class selector and member selector drop downs, and then use regions to keep the code clean (of course, i don't make the regions myself, i have use regionerate to group and sort everything).
But that's just my preference
Darren Kopp on July 7, 2008 9:25 AMGood comments Jeff. I've long since strayed off the MS path and its amazing how much a free product like Eclipse can still trump the golden child of IDEs (VS) after all this time. Granted, IBM has dumped buttloads of cash into Eclipse but still...no excuse for mucking up your LANGUAGE with something that a smart editor can handle. Rofl, cakes.
I think crap like this is whats pushing talented coders away from the lower level languages and making them fall in love with Ruby and Python. They just want to get stuff done and not worry about junk that slows them down.
Adam Conroy on July 7, 2008 9:25 AMYou're spot on! Regions seem to flap about and get in the way of getting on with it. And dangerously folks seem happy to dunk stuff into a region, when they're too lazy to refactor code into a new class.
And Ctrl-I ... so few of my colleagues seem to use it. It makes me cringe when I see people Ctrl-F'ing slowly about because they don't bother to learn their tools. And, why do so many programmers seem to refuse to learn to touch type? It only took me a couple of weeks to get into, but makes working with a computer soooo much more fluid!
Scott on July 7, 2008 9:31 AMYou have good points there. I personally don't want to see loads of verbose code that is the result of adding some fancy new technology to the project. But that verbosity is possible to be hidden by encapsulating, not with regions.
For example you all remember The Evolution of Programmer example of coding levels: Basic programmer, advanced programmer, expert programmer etc., where the basic programmer does only 10 Print Hello World 20 Run, but master programmer has already pages of advanced C-code.
http://www.thehumorarchives.com/joke/The_Evolution_of_a_Programmer
This is obviously a preference that can be overused. Just like pretty much everything else, it has its place if used correctly.
I feel more strongly about overuse of comments and even worse, inline suppression of Code Analysis...talk about making your code not readable.
BZ on July 7, 2008 9:32 AMRock Scroll. Use rock scroll. See your code from on high and from down low all at once. Avoid regions. Use rock scroll. Rock scroll ftw.
Damn it's good. http://www.hanselman.com/blog/IntroducingRockScroll.aspx
Hmm. I was going to argue that with proper use, #region is not so bad, but then I remembered a recent gem from a college. Here's a rough outline:
if (some condition)
{
I use Vim, by the way, and it's configured not to fold anything unless I explicitly ask it to.
Right, Vim does it correctly, I think, and has a tremendous amount of power available to it (though you have to slog through a bunch of documents to see all the features).
It folds on a number of things, none of which masquerade as preprocessor statements.
Have a tremendously long switch statement containing a line or two of code for every letter in the alphabet? Tap two keys and vim folds down all the code within the nested brackets, allowing you to just look at the case statements. Etc.
Bill on July 7, 2008 9:46 AMSorry for the double post... keyboard error.
Hmm. I was going to argue that with proper use, #region is not so bad, but then I remembered a recent gem from a college. Here's a rough outline:
if (some condition)
{
#region Foo
...
}
if (some other unrelated condition in another block)
{
...
#endregion
}
Jeff,
if code is not readable, or if it is readable only if folded, it is very likely that it is not the best cut of code.
Folding is for laundry. Optimization/Refactoring is for code.
BugFree on July 7, 2008 9:47 AMI call it cheating.
Duk on July 7, 2008 9:49 AMI agree with Jeff enitrely about this, though I am not neccessarily qualified to comment.
I'm a PHP5 developer and I use EditPlus as my editor. It has a kind of 'hacked in' code folding which turns out to be exactly what I want - it gives you the little expand/collapse button for any section of code that is at the same level of indentation. Its not very elegant but it has a suprisingly high percentage of the value of real code folding without any of the effort. (Your code is all properly indented, right?)
I don't need to hide away class attributes, getters and setters and such because PHP doesn't have any of that crap unless you want it - and then you want to see it. What I *do* sometimes want to do is things like collapse the 'true' section of a large
if( ... )
{
...
}
else
{
...
}
block so I can see the condition right next to what happens if it is false. Or hiding away divs in a HTML/template file so that I can see the surrounding structure (hunting for that unclosed tag!).
It is zero effort on my part and is there for the very rare occassions that I want to use it. If you want to give your region a description, just use a comment :p
Mat Scales on July 7, 2008 9:51 AMI prefer KDevelop/Kate's way of handling it: Every block-level statement (ie, anything within braces) is collapsible. So are similar block-level statements in languages like Python, which don't use curly braces.
In KDE4, Kate is also capable of highlighting a block if you mouse-over its collapser...
And yes, it can handle #regions inside C# code too! I just tried.
shash on July 7, 2008 9:57 AMclearly, all those years of web developing have saved you from seeing any problems, which actually do require a huge ugly block of code to solve... :P #region is handy if you have such a block of code, and with MSVS its neatly wrapped into the ide so you just select the area and choose to outline it.
generally i am in favour of splitting things out into seperate files, however once it gets down to the one method level, i think its pretty silly to split it into more procedures/functions just for the sake of keeping it in smaller chunks. sure you /can/ wrap it into lots of little procedures, but i'm not a fan, as it breaks the ability to read the whole code in sequence without swapping files, or moving around in a large file.
at the end of the day if you want to see what is in the region, you expand it... i really fail to see the big deal there as encapsulating things in procedures has precisely the same problems in terms of maintainability and readability which have been described in the article for regions, except for that nebulous point about it being like a glorified comment... if anything its slightly worse because you can't expand the procedure in place to see its precise effect, but need to use some (implicitly error prone) thinking to substitute variables and remember things between two different files etc...
can anyone remember the early visual basics btw? they had this awesome feature where by you looked at one procedure at a time in the editor, even though they all came from the same file. its a shame they dropped it in vb 5 or 6 (can't remember which). i think that old feature is a much, MUCH, better solution than what we currently have in the more recent visual studio products.
Jheriko on July 7, 2008 9:58 AMJeff, Jeff, Jeff...
Have you truly LOST it and gone all religious on us? It's a formatting technique, my friend. Properly used, folding regions allow us to reduce the problem set by managing the complexity of a code file. That IS what our friend Steve McConnel preaches, isn't it? That our goal is to manage complexity?
With strategic use of folding regions, we can keep the screen clear of code irrelevant to our immediate purpose. Your argument that irrelevant code belongs in a different file depends entirely on context: the small part of the code I am working on may very much belong in the file, but I don't want my eyes continually distracted by code for methods and such that have nothing to do with the particular problem I'm working.
How do YOU know what I want to focus on? What SPECIFIC thing I'm trying to understand or debug? How do YOU know that the best way to organize my code for focusing on one problem may be completely counterintuitive to the solving of a different one? Being able to collectively collapse/expand regions of the code AS NEEDED is a great way to keep your mental focus flexible.
I'm a fan of yours, and I mostly agree with your musings/insights, etc., but I'm afraid if we were on the same programming team, I'd be standing my ground on this one.
Wing Flanagan on July 7, 2008 9:58 AMshash: visual studio provides the same functionality out of the box, minus the selection thing you mentioned, which does sound useful. :)
Jheriko on July 7, 2008 9:59 AMI think Regions were introduced to .NET because the Microsoft programmers had the problem of autogenerated code. They needed a way to tell us hands off to the Web Form Designer Generated Code section. In 2005 and beyond, they simply introduced another feature, Partial Classes, that got rid of the the horrible hand off region section. Now, the MS developers can put all of their code in one file, and leave a clean file for us to work in.
I will second the comment that someone above made about VB6. There was a button in VB6 that you could press to view only the currently selected function. I used this all the time in order to make my scroll bar increase from hairline size to something I could actually click on.
In my opinion, regions and collapsible code have the same function in that they allow you to shrink the size of your scrollbar at will.
Generally, I think #regions are helpful, when used in moderation. I like each of my files structured similarly (declarations first, properties second, events third, and public/private methods last). Because of this, I usually wrap the declarations, properties, or both into #regions so that when I open a file, I don't see a bunch of rarely touched code. When you say that everyone should be able to see all the (crappy) code, I agree; however, I don't think we should have to look at a few pages of declarations/properties that are probably fine. If I know there is a bug on Page_Load, I don't want to have to scroll down a ways to see the beginning of it. Also, this doesn't take much time to type. When I create a new file, I easily the #regions using a code snippet on my machine. You said that the editor should automatically offer to fold up these common structural blocks for you! Unfortunately, this doesn't happen now, so I will have to do it in the meantime. If the next version of Visual Studio starts to do this, then maybe I will drop #regions altogether.
Mike on July 7, 2008 10:04 AMWhy, exactly, are we writing code to accommodate the editor? It boggles my mind that we'd add significant lines of code to our project that do nothing but offer organizational hints to the editor.
Did you actually say that?
I hope you are not wasting your time filing your documents in relevant folders, only to have the cabinet look organized. Geez… the health insurance cover isn’t going to increase just coz you filed it! And also you should spread them all out on your floor, so that you can see ALL of them ALL the time.
Reducing visual noise is a wonderful thing. If I don't currently need it, I don't want to see it. Within code files, MS chooses the plus/minus expand/collapse approach as a big stick to get this accomplished. Regions allow us to introduce collapsibility into our code that isn't provided out-of-the-box.
This is analogous to menus, treeviews, toolbars, etc in UI design. You can use these organizational tools to make things easier to use and find, or you can create a mess.
Whether you implement regions in a useful way is up to you.
Chris on July 7, 2008 10:05 AMYou're not just advocating abandoning #region you got it in for comments to!? You gone CRAZY man!
Ditching regions and just having the option to have it open folded down to signatures would work for me, but that said I'd also like some options to allow me to sort methods (in a similar way to the current sort usings). I think that maybe because I also like to use class and method selector drop downs, as well as right click - go to definition, so alphabetical works for me.
As for comments I think I'd like to see the class and method comments moved to a seperate file as they've rarely been useful on code I'm working on. I've only really found them useful when you got the dll for some third party library and no source to reference, even then I've often had to resort to reflector to find out what's going on as they're often written by people who know how the library works without enough consideration for those who don't.
MarkM on July 7, 2008 10:08 AMLike most things, I have no problem with regions when used in moderation. For example, in my current environment, we have classes that have a lot of constants (sometimes as many as 100) inside of a single class. It's nice to wrap these up in a region, as well as other code that's important for the process to function but not important to look at.
Test fixtures are another place that I occasionally use regions. There may be a few hundred lines of SetUp and TearDown, which aren't interesting once it's completed.
But I do agree that regions just for the sake of having them is usually unnecessary. I definitely don't like the regions used in the sample in this article - if you're going to use them over an entire codefile, I'd rather see them as logical groupings instead of just by the type of members.
Joe Enos on July 7, 2008 10:10 AMThose who point out auto region expanding miss the core problem with regions -- if your coworkers are praying at the idol called regions, that externality infects the codebase. It strongly motivates how the code is structured, conforming with a generally poorly thought out use for regions.
Seriously, when people talk about accessibility or finding methods / properties / fields, and how regions help the same, it screams from the mountaintop that they are woefully unaware of the rudimentary features of the IDE (guess what -- it already tracks all of these, each navigable in the desired manner when the need arises).
Dennis Forbes on July 7, 2008 10:11 AMJeff, I think you take this a bit too far. Firstly, you get a little sloppy with your argument:
The editor should automatically offer to fold up these common structural blocks for you!
This came *right after* all the argumentation that folding is so bad because it hides code that shouldn't be hidden (which I happen to think was good argumentation).
One other thing - folding can be useful without all the problems you have with it. Take Emacs folding for example - if you need to refactor a function, but don't know all the commands or keyboard combos that have regional effect instead of buffer effect, you can use folding to put a region into a buffer of it's own, and then use buffer-wide commands there, and then jump back into the original buffer with the edits you made intact. Folding can be useful for things other than just hiding code.
aggieben on July 7, 2008 10:15 AMJust a quick comment to say *Thank You*, Jeff.
I just had a bad, bad, bad moment last week when I opened the Nth file that was all #region-ed. My scream of 'AAARGH !' was greeted by blank stares (and a few bad looks) in the room. sigh
I use 'vi' folding with 'set foldmethod=marker' all the time.
I only fold up functions, however, and my 1st line of the fold has enough info to infer what the function does.
This allows me to see what functions are available at a glance,
while working on the main body of the code (or while looking at a new function in progress).
vi (actually vim) will drop me back off where I was upon opening the file, so if I'm already in a fold, it's open when I start.
When working with fairly standalone application and a small developer base, the codebase resides nicely in a single file. This helps hide any deficiencies in the infrastructure, such as poor installation/distribution support and versioning :-)
So I find the ability to fold code (and textfiles of notes) very valuable... but with any 'feature' of the editor, it can be abused.
Jeff,
Not being very constructive now, are we? Sure regions can be bad when used in the wrong way, as stated in many of comments. I can feel your pain since the code I'm working with atm is full of all the wrong kind of regions. But that is no reason to outright outlaw the usage of regions. Used in the right way they can be quite a help.
Better to educate the community of when and how to use regions and in the end we will all be better off.
Robert Hglund on July 7, 2008 10:20 AMIt isn't hard to toggle outlining, are we really getting to the point where we're complaining about the effort involved in hitting a shortcut key?
I use regions quite often, but I also treat them a little differently. I keep them all expanded, but I color the directives a bright pink so they stand out. I use these bright pink directives to group static members from instance members, properties from methods from events, etc. I can quickly see them as I scroll through the file. You can also quickly jump to regions if you're consistent in your naming.
Brett on July 7, 2008 10:28 AMI have been usisng a folding editor for 10 years or more. yes it can hide lots of bad code, but conversly, when I open a file I can see instantly in front of me the structure of the module. Without folding I temd to see half a page of includes, and quite often some helper functions - this does nothing for me.
Our deperatment is fairly 50/50 split on folding, but we all get along!
In addition to my previous comment, regions are great in WPF when you don't want to see all the junk associated with dependency properties, routed events, etc.
Brett on July 7, 2008 10:32 AMCount me in as fan of regions. As others have said, they are useful for hiding the likes of numerous attribute declarations, etc.
However, I do agree with most of your objections, they are very prone to abuse. Many times the desire to use a region can be taken as an opportunity to consider refactoring. That's the clue I use personally in any case.
I also feel your pain, there is a member of my team who shall remain nameless that insists on profuse (imo) use of them. It is painful to read files he's written.
Seth on July 7, 2008 10:39 AMRight click, Outlining, Stop Outlining.
Job done. But you knew that already.
Meh. I think the most important takeaway here is that #regioning is a code smell. For me, I don't see much regioning since I usually browse by Go To Definition, which necessarily expands the region.
John on July 7, 2008 10:54 AMSounds like most of the proponents of code-folding believe that it reveals the outline by hiding the details. I submit that, when we're looking at code, the devil is in the details
Regarding partial-classes, my .02 is that they should only be used to separate auto-generated code from programmer-generated code.
@Wile_E_Coyote:
As I said above, if you have to delve into the implementation of a class before you can use its public interface then that is a definite code smell!
Graham Stewart on July 7, 2008 11:11 AMI do not know how Visual Studio works, but emacs incremental search is so not-painful to use that I can't really express it. I see this folding feature that my friends from college use and I have been only disgusted with how much time they lose using the mouse to code while using it (and other features from those fancy IDEs).
I have been using XEmacs to program in C for some months now and I can say that I will probably still use it for the rest of my life.
I used to commonly write a class and then reorganize my methods into groups that were logically related. Once I had all these nicely formatted regions I would then realize that each one represented a class that my original class should be refactored into.
Of course, I didn't refactor; I just stopped using regions.
@Tom: The best part about that is that no matter your preference on this issue, both sides can peacefully co-exist!
Adam on July 7, 2008 11:21 AMI've got two outline regexps for C++ in Emacs. One uses only method names and doxygen headers, the other adds on method-internal comments.
I defined these at first to get the IDE feature into Emacs, but I've stopped using them lately. Between tags-apropos and C-s/C-r I haven't needed folding.
Remember what Steve Yegge said about arranging stacks of screens of Tetris games? The #region problem is a symptom of your larger issue: boilerplate demanding superhuman code organization. You need an IDE so you can use your IDE. I think he's got you on this one.
Dan Lewis on July 7, 2008 11:34 AMWhen you open up to some nicely collapsed regions, that energy is saved and you can quickly find the relevant section of code.
Not necessarily. You might spend more energy trying to work out if the relevant section is Handlers or Miscellaneous. Or worse, protected functions or public functions.
The major problem here is that region is either semantically defined, which varies wildly by programmer, or syntactically defined, which normally means that they've taken the one bit the editor handles most easily (sorting/filtering functions by privacy level), and layered a fold over the top. This would be fine if protected and public functions were always clear from context. But as there's no reason every function in your code can't be public, as long as everyone agrees never to use them (private by mutual consent *guuuh*), this simply isn't reliable,
The main issue i have with regions is it forces all viewers into the same visualization of the code. Weather or not it is a good organization or not it forces that View of the code on the reader. When a class with regions are poorly organized it harms all viewers.
And poorly organized is relative to the ideal conceptualization you need, ie: the mental picture.
The most common and in my mind most annoying #regions are grouped by:
ctor
fields
properties
methods
Why? This is arbitrary organization based on the parts and not a conceptual model. It would be like organizing a book based on verbs, nouns etc instead of the normal conceptual model, units of time (ie chapters).
Good organization would be regions based on Interface implementations, Class overrides etc.
For instance:
# IPerson
# Control visual element hook-up
This organizes based on logical separation of concepts.
However this is still not perfect. Because any newcomer to the code will be forced to view the code with the organization I chose in my regions. If that organization doesn't work for what they are doing(the conceptual model they need), they are forced to work against that model. They will end up expanding the regions, trying to block them out mentally, while attempting to make the code coherent in their mind.
brian on July 7, 2008 11:42 AM@Paul
There's a lot of things Visual Studio could do better if Microsoft bothered to copy the competition.
Correction:
There's a lot of things the competition could do better if they bothered to copy Visual Studio.
C'mon, the last time I tried Eclipse (no that long ago), it didn't even have File | Save As. Not in every case, but generally speaking, Visual Studio let's me get my work done without a lot of BS. Most of the competition may have some fancy new features that are very well done, but then basic stuff that Turbo C++ had 20 years ago isn't even there.
I definitely think it is very bad practice to utilize editor/IDE tricks to avoid having to make things readable. Just hiding the ugly bits of the code, instead of actually spending the time thinking about it and finding a cleaner way, is just another lazy way of injecting spaghetti into your system (gotos were useful too). It is the type of problem that only gets worse with time. It is far easier to make a mess, then it is to write decent code.
Paul.
http://theprogrammersparadox.blogspot.com/2008/06/readability.html
This is a lot like the 'var' discussion. Yes, in the wrong hands it can be misused. If you're a bad programmer, you'll always be a bad programmer, no matter what language, Studio, or how many or how few language features.
Don't gimp my language/tool because someone else might misuse it!
This is why everything comes with a damn warning label: Caution: if you're a moron you might cut yourself with this knife.
Dennis on July 7, 2008 11:47 AMEMACS
I want my editor back!
1970 on July 7, 2008 11:49 AM'Don't gimp my language/tool because someone else might misuse it!
This is why everything comes with a damn warning label: Caution: if you're a moron you might cut yourself with this knife.'
Dull knives cut fingers... not sharp ones.
@Paul: I definitely think it is very bad practice to utilize editor/IDE tricks to avoid having to make things readable
It's worth pointing out that #region is NOT an editor/IDE trick.
It is a recognised part of the C# language, according to the ECMA standard:
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf (see section 9.5.6)
Emacs is getting a lot of attention in this post. I think it's because it was the first IDE (or one of the first), so basically everybody wants to compare a cool feature with the one that is presented in emacs. Emacs is so, so old that is hard to consider anything that does it differently from Emacs to be better. For most things that is true, for others it's just a different convention derived from the enviroment. In the case of incremental search I belive it's hard to be better than emacs, ctrl+s to incremental search forward from the cursor, ctrl+s again to search for the next word, the same with ctrl+r for backward search.
Hoffmann on July 7, 2008 12:11 PMI've been reading this blog for a few years now and I normally agree with about 90% of what Jeff writes about, but I highly disagree on this matter. While writing clear, concise, logically-organized code is certainly the goal, we all know it's not always possible. I do the best I can, but there is often a lot of extra setup code and such that I don't need to see while I'm working on other things.
And having wrestled with ADHD/Primarily Inattentive Type thoughout my life, the ability to easily hide sections of code that I don't need to be concerned with at the moment is probably my single favourite feature in VS.NET (as compared on VS 6.0). It's a huge productivity booster for me to be able to selectively hide pieces of code that distract me and contribute to mental clutter. I would guess that most programmers probably can't relate as I don't think that the ADHD brain style is especially suited to the task of programming.
Keldryn on July 7, 2008 12:18 PMIf your boss looks at this folded code he is going to think, I pay you all this money and you have not written any code
:)
rippo on July 7, 2008 12:20 PMWell, overusing regions is bad practice, I agree. But this is another way for structuring the code, like splitting the classes to files. The same way one might say, that all the code should be in one file, because then you won't need to browse a huge solution tree. Just one file and ... incremental search ...
Papi on July 7, 2008 12:22 PMIt large files this is incredibly helpful... less you scroll forever and ever to find what you need. The extra mouse click to open them is well worth the time it would take to scroll through a whole bunch of stuff you don't need.
Kris on July 7, 2008 12:28 PMI initially didn't like regions, but then I started working with larger code files and realized how useful they can be. My biggest disagreement with Jeff's four points is number 3. Sometimes you may have a perfectly clean code file that simply *has* to be long, for various reasons, and regions make it easier to get around and find the parts you're looking for. So put me down in favor of #region.
Chris Tybur on July 7, 2008 12:36 PMI love regions. If you did a survey, I bet 90% of
Visual Studio developers will say they use regions
and love them.
I think that it might be good to point out that the editor in question already does code folding on the function level (and the xmldoc comments have built in folding already too). regions are a way to group collections of functions into a higher level bucket that can be folded at one time.
That being said, I prefer smaller, lightweight code bases that do not require massive folds to make things manageable.
Ben Evans on July 7, 2008 12:49 PMIt often amazes me how narrow minded and black and white we coders are. Everything must fall into good or bad buckets.
Yes, if you write crappy code and then hide it #regions then your a loser, but it isn't the #regions that made your code worthless...It's your code. Taking it out of the regions (or putting it in) didnt change the code.
Instead of looking at it a hiding, I prefer to think of it as black boxing. That code is solid and stable and doesnt need to be thought about.
But this idea of whining because we had to set one more config option in order to not have to expand the code manually is a little absurd.
I would rather see that someone took the mental-time to organize the code in some fashion than to have to hunt all over to get from method to method.
Just my two-cents....
Baffled on July 7, 2008 12:52 PMI used to think that regions were great until I opened up a file that someone else had written and all of the code was folded. It was a waste of my time to have to unfold it all so that I could read the code and get on to my task. Now I don't use regions. I also disagree about folding comments. If the comments are useful than they should be visible. If there is a reason to hide them in a region, then maybe the comment shouldn't be in the file.
asm01asm on July 7, 2008 1:03 PMWhy are people complaining about code-hiding? We do it everytime we create a class file. If you don't loke hidden code, then by all means code in a text editor. Textpad is where I do most of my coding in. Sure it doesn't do any autocompleation or other nifty gadgets, but your code is EXACTLY the way you want it.
sarcasmMake everything Global while you are at it. After all Global vars and expressions are faster and cleaner./sarcasm
Right on, Jeff! In practice, regions are a band-aid on bad code. They seemed nice when they were first introduced. Now, I wish they'd never been introduced. They give the illusion of nice, neat code. If you need to organize the code, use the language elements to do it. Also, I can't stand having to open those damned things up. I don't need all the properties in one place, all the private methods, in another.
I have to agree, but it's an opinion I don't hold as strongly. They annoy me, but I don't actually hate them.
Jeff Davis on July 7, 2008 1:29 PMIn 2005 and beyond, they simply introduced another feature, Partial Classes, that got rid of the the horrible hand off region section.
This is a great point -- until Partial Classes existed, #region was necessary to hide the required generated code.
As for comments I think I'd like to see the class and method comments moved to a seperate file, as they've rarely been useful on code I'm working on. I've only really found them useful when you got the dll for some third party library and no source to reference.
The presence of massive XMLDoc comments bothers me as well. It's necessary, but it gets in the way so often.
The fact that we even *have* a #region directive is part of the problem. With a good editor it shouldn't be necessary, and all folding would be optional. I wish the Visual Studio editor was smart enough to fold XML Comments down automatically -- or even fold down methods automatically. It's not, even in 2008. Example here:
http://www.codinghorror.com/blog/archives/000332.html
Jeff Atwood on July 7, 2008 1:29 PMI have read about this kind of VS code folding before and I did not like the sound of it at all. I have never liked any kind of code folding at all until i started using mylyn (except maybe some minor imports and comments folding).
Eclipse + mylyn that does class/project tree folding and source code folding that is associated with a task. The task can be an issue in an issue tracker and you can save the task's folding into the issue tracker. It is really good when working with both big and smaller sets of files.. I guess that most of you know this but anyways...
Here is some information on mylyn folding: http://www.ibm.com/developerworks/java/library/j-mylyn2/
A lot of people here seem to think that regions are the *only* way to hide code. But they're not the only way, nor even the best way. Here's a better way.
In VS, go to Tools Options Environment Import and Export Settings. Copy the path and filename in the Automatically save my settings to this file box. Then open that file for edit. (Not sure if you can do this in VS and still have it work right, but otherwise use some other XML editor.) If in VS, hit Control-K, Control-D to format the whole file so it's readable.
Find the KeyboardShortcuts section. Then find the UserShortcuts section within that. If you've customized your keyboard at all, you should see various lines starting with Shortcut or RemoveShortcut. (If you can't find these sections, go into Visual Studio, customize a keyboard setting, then open the .vssettings file back up and look again.)
In among the Shortcut/RemoveShortcut lines, paste these:
Shortcut Command=Edit.ToggleAllOutlining Scope=GlobalAlt+Right Arrow/Shortcut
Shortcut Command=Edit.ToggleOutliningExpansion Scope=GlobalAlt+Down Arrow/Shortcut
Shortcut Command=Edit.CollapsetoDefinitions Scope=GlobalAlt+Left Arrow/Shortcut
RemoveShortcut Command=View.Forward Scope=GlobalAlt+Right Arrow/RemoveShortcut
RemoveShortcut Command=Format.SpaceAcross Scope=VC Dialog EditorAlt+Right Arrow/RemoveShortcut
RemoveShortcut Command=Edit.CompleteWord Scope=Text EditorAlt+Right Arrow/RemoveShortcut
RemoveShortcut Command=View.NavigateForward Scope=WebBrowserAlt+Right Arrow/RemoveShortcut
RemoveShortcut Command=Format.SpaceAcross Scope=VC Dialog EditorAlt+Left Arrow/RemoveShortcut
RemoveShortcut Command=View.Backward Scope=GlobalAlt+Left Arrow/RemoveShortcut
RemoveShortcut Command=View.NavigateBackward Scope=WebBrowserAlt+Left Arrow/RemoveShortcut
RemoveShortcut Command=Format.SpaceDown Scope=VC Dialog EditorAlt+Down Arrow/RemoveShortcut
What does this do? It remaps some Alt+arrow keys. Alt-Left now does Collapse to Definitions; Alt-Down toggles the item you're on; Alt-Right toggles the whole file between completely expanded and completely collapsed.
So when you open up a code file and the code is sprawled everywhere, just hit Alt-Left and it collapses neat and tidy, but you can still see the members. On the member you want to work on, hit Alt-Down to open it. (Or just double-click on the [...], of course.) If your file contains several classes, use Alt-Right (you may have to hit it twice) to collapse everything, even the class definitions, so you can open just the class you want.
All the code hiding you could ever dream of, and you don't have to use regions for any of it.
Kyralessa on July 7, 2008 1:30 PMWhat's the big deal against regions? It's just a cheap IDE trick - didn't Code Complete wish this existed a while ago? Any feature/trick can abused if misused by an bad coder.
I peronally love them - I hide away my member/property declarations for when I'm not dealing with that stuff and working on business logic. Sure I can scroll to the bottom, but why bother every single time? I use it as a part of a naming/layout standard - which I actually picked up from a dev team on a gig.
As per my twitter post - you're illogical to me on this one - I think implicitly typed local variables can get you in about a billion times more trouble in the wrong hands than regions.
BPAndrew on July 7, 2008 1:31 PMIs it okay to trash developers that are no longer on the team? :)
thedp on July 7, 2008 1:32 PMI agree with you 1000%, Jeff. I think the comment regions are a code smell is spot on. Using regions to organize code or manage complexity is using them as a crutch to enable inordinately long code blocks and poorly factored classes. A class or method that is complex enough to need regions is almost certainly doing too much.
I too hate the fact that when you open the code in the editor you don't see the code. If I didn't want to see the source, I wouldn't open it, dammit. I always disable automatic auto-outlining in Visual Studio for that reason (and region generate for interface implementation as well).
I also find that regions are rarely applied consistently. Some people fold by property/method/constructor. Others by public/private/protected. Neither really add any value, they just make it harder to navigate the code.
I have to completely disagree. Boilerplate crap is a fact of life in the Windows programming world, and the #region directive brings some kind of sanity to that.
If you really want to navigate your code base you're not doing it by scrolling through a single file's edit window anyway; you're using Ctrl-F12 to skip through definitions or using the class browser.
Andrew on July 7, 2008 1:40 PMI'm not sure if that's been mentioned before and I'm not ready to read 150+ comments (sorry!) but I think I've got a point worth mentioning.
I believe that, unfortunately, and despite good intentions, Regions should be considered evil. Why? Because they lie. Region titles make strong claims, e.g. “Private members” claims that this region only contains private class members. But of course, the compiler won't check this assertion, it won't check whether the region really doesn't contain public methods.
I've come across situations where I've searched myself silly because the region captions were lying to me (and yes, I wrote these captions so I'm guilty). But the fact remains that this has cost me much time and I have learned to give any constructs that give redundant, unchecked information a very wide berth. Regions, in my opinion, are very good at hiding vital information while making false claims.
Konrad on July 7, 2008 1:47 PMRegions are an organizational tool. They can be very helpful, and if you haven't found them to be so, then that's fine. I've yet to run into a situation where regions were involved and my life was on the line...maybe everyone else here works in a more intense environment than I do.
Outlining can be turned off within Visual Studio, and as it has been pointed out, everything can be expanded in a couple of quick clicks. So it seems like the worst your co-workers have done is added a few goofy lines (similar to some odd form of commenting) to the otherwise pristine code. Since any good code file is apparently contained in approximately one to two pages (as I've learned from the comments), then I don't see that this is really worth mentioning.
It seems to me that the two arguments that keep coming up against using regions, have boiled down to something like this 1) I've seen abuses of regions, therefore regions suck, or 2) *I* don't like regions; therefore regions have no value; therefore if *you* need to use regions, then you're obviously not up to snuff on your mad koding skillz!1. There's some dogmatic assertions here today.
And besides, if you don't see the usefulness of regions, then, obviously, you're doing it wrong ;)
I'll have to back up the VI (VIM) comment above. VI has great code folding. You can specify how it folds and tell it to remember your folds open/close when you come back to the file later (plus remember where your cursor should be).
Hard to be the efficiency of VIM if you know your language.
The comments to this entry are closed.
|
|
Traffic Stats |