Stop Visual Basic 6 from changing my casing - vb6

Very simple question that is apparently impossible to find a decent answer to: How can I make Visual Basic 6 stop changing my ^##*ing variable casing!?!
I know that the general opinion of a great many VB users is that this "feature" is actually quite helpful, but I doubt that they use it much with any source control system. This is absolutely INFURIATING when you are trying to collaborate on a project of any significant size with several other developers. If ignored, you produce thousands of false-positive "changes" to your files (even ones with no actual code changes!) that pollute the revision history and make it near impossible in some cases to locate the actual change that took place.
If you don't ignore it (like my office, where we have been forced to implement a "no unneeded case change" policy), you spend 5x the time you would normally on each commit because you have to carefully revert out VB's "corrections" on every file, sometimes reverting hundreds of lines to put in a one line change.
Surely there must be a setting, plugin, hack, etc. out there that can remove this unwanted "feature"? I am willing to take any method I can get as long as it doesn't require me to pick through piles of phantom diffs. And to squash a couple of complaints up front: No, I can't turn off case detection in my diff tool, that's not the point. No, we can't just make the case changes globally. We're working with hundreds of thousands of LOC being worked on by multiple developers spanning many years of development. Synchronizing that is not feasible from a business standpoint. And, finally: No, we cannot upgrade to VB.net or port to another language (as much as I would love to).
(And yes, I am just a tiny bit peeved at the moment. Can you tell? My apologies, but this is costing me time and my company money, and I don't find that acceptable.)

Depending on your situation adding
#If False Then
Dim CorrectCase
#End If
might help.

Here is a real world scenario and how we solved it for our 350k LOC VB6 project.
We are using Janus Grid and at some point all the code lines which referenced DefaultValue property of JSColumn turned to defaultValue. This was an opportunity to debug the whole IDE nuisance.
What I found was that a reference to MSXML has just been added and now the IDE picks up ISchemaAttributes' defaultValue property before the Janus Grid typelib.
After some experiments I found out that the IDE collects "registered" identifiers in the following order:
Referenced Libraries/Projects from Project->References in the order they are listed
Controls from Project->Components (in unknown order)
Source Code
So the simple fix we did was to create a dummy class/interface with methods that hold our proper casing. Since we already had a project-wide typelib we referenced from every project before anything other typelib, this was painless to do.
Here is part of the IDL for our IUcsVbIntellisenseFix interface:
[
odl,
uuid(<<guid_here>>),
version(1.0),
dual,
nonextensible,
oleautomation
]
interface IUcsVbIntellisenseFix : IDispatch {
[id(1)] HRESULT DefaultValue();
[id(2)] HRESULT Selector();
[id(3)] HRESULT Standalone();
...
}
We added a lot of methods to IUcsVbIntellisenseFix, some of them named after enum items we used to misspell and whatever we wanted to fix. The same can be done with a simple VB class in a common library (ActiveX DLL) that's referenced from every project.
This way our source code at some point converged to proper casing because upon check-out the IDE actually fixed the casing as per IUcsVbIntellisenseFix casing. Now we can't misspell enums, methods or properties even if we try to.

SIMPLE WAY: Dim each variable in the case that you want. Otherwise, VBA will change it in a way that is not understandable.
Dim x, X1, X2, y, Yy as variant
in a subroutine will change ALL cases to those in the Dim statement

I can sympathise. Luckily we're allowed to turn off case sensitivity in our version control diff tool!
It seems the VB6 IDE automatic case-correction occasionally changes case in variable declarations and references, perhaps depending on the order in which modules are listed in the VBP file? But the IDE doesn't tell you that the file needs to be saved. So the problem only shows up when you saved the file because of another edit. We briefly tried to prevent this by checking out all the files in a project and setting the case carefully, but it didn't go away.
I suppose you could list the variable names that are affected - the usual suspects are one letter names like "I", "X" and "Y", perhaps because they are used in standard event handlers like MouseDown. Then write an add-in that'll search for all declarations " As" and force the case to upper. Run the add-in on your modules before you check them in. You might be able to trigger the add-in to run automatically when you save in VB6.
EDIT: Something I've just thought of: adapt Fred's answer. From now on, every time you check in a file, add a block at the top to establish canonical case for the usual suspects. If nothing else, it's easier than reverting hundreds of lines by hand. Eventually you will have this block in every file & maybe then the problem will stop happening.
#If False Then
Dim I, X, Y ' etc '
#End If

I standardised the case across the codebase, normally by using the examples above (Dim CorrectCase), and removing it again.
I then triggered VB to save EVERY file, by doing a case sensitive search/replace of "End" with "End" (no functional change, but enough to get VB to resave).
Once that was done, I could then do a single commit to standardise the case, making it MUCH easier to keep on top of it at a later date.

In this example VB6 was changing the case of the following line following a typo I made when referencing a library: -
Dim MyRecordset As ADODB.REcordset
Ugly, and now every other instance of an ADODB.REcordset thus acquired the new misspelling. I fixed this as follows: -
Type in a new declaration as follows
Dim VB6CasingSucks AS ADODB, Recordset
Note the comma and space after ADODB. Hit [ENTER] for VB6 to check the line.
At this point all instances of REcordset change back to Recordset.
Delete your new declaration.
I don't know if this fix will help with enums/other variable names.

Specifically for controlling the case of enum values, there is a VB6 IDE add-in which may be helpful. Enums seem to have a slightly unique version of this problem.
As described in the link below:
The VB6 IDE has an annoying quirk when it comes to the case of Enum
members. Unlike with other identifiers, the IDE doesn't enforce the
case of an Enum member as it was declared in the Enum block. That
occasionally causes an Enum member that was manually written to lose
its original case, unless a coder typed it carefully enough.
...
However, if a project contains a lot of Enums and/or a particular Enum
has a lot of members, redeclaring the members in each of them can get
quite tedious fast. ...
Ref: http://www.vbforums.com/showthread.php?778109-VB6-modLockEnumCase-bas-Enforce-Case-of-Enums
...load and unload the add-in as needed via the Add-In Manager
dialog box. Usage is as simple as selecting the entire Enum block,
right-clicking and then choosing the "Lock Enum Case" context menu
item.

I have a similar problem:
in a bas module there I wrote :
Private sub bla_bla()
Dim K as integer
End Sub
so in a class module the Dim k as integer will automatically be replaced by IDE become 'Dim K as integer' <-- it's not logical but then:
I correct the bas module become:
Private sub bla_bla()
Dim k as integer
End Sub
then magically the problem in the class module was solved (still be k and not automatically replaced by IDE become K). Sorry I'm poor in English

I don't think there's any to do it. The IDE will change the case of the variable name to whatever it is when it's declared. But, honestly, back in the day I worked on several large VB6 projects and never found this to be a problem. Why are people on your development team constantly changing variable declarations? It seems like you have not established a clear variable naming policy that you enforce. I know your upset, so no offense, but it might be your policies that are lacking in this regard.
Unfortunately, according to this SO thread, alternate VB6 IDEs are hard to come by. So, your best bet is to solve this problem via policy. Or move to VB.NET. :)

Wow. I've spent a lot of time programming in VB6 and I have no idea what you're on about. The only thing I can think you're referring to is that intellisense will change the capitalization of variable names to match their declarations. If you're complaining about that, I would have to wonder why the hell they've been entered any other way to begin with. And if that is your problem, no, there's no way to disable it that I'm aware of. I'd suggest you, in one go, check out every file, make sure the caps on the declarations and uses of variables all match and check back in.

Related

What is the difference between Form5!ProgressBar.Max and Form5.ProgressBar.Max?

I'm looking at a piece of very old VB6, and have come across usages such as
Form5!ProgressBar.Max = time_max
and
Form5!ProgressBar.Value = current_time
Perusing the answer to this question here and reading this page here, I deduce that these things mean the same as
Form5.ProgressBar.Max = time_max
Form5.ProgressBar.Value = current_time
but it isn't at all clear that this is the case. Can anyone confirm or deny this, and/or point me at an explanation in words of one syllable?
Yes, Form5!ProgressBar is almost exactly equivalent to Form5.ProgressBar
As far as I can remember there is one difference: the behaviour if the Form5 object does not have a ProgressBar member (i.e. the form does not have a control called ProgressBar). The dot-notation is checked at compile time but the exclamation-mark notation is checked at run time.
Form5.ProgressBar will not compile.
Form5!ProgressBar will compile but will give an error at runtime.
IMHO the dot notation is preferred in VB6, especially when accessing controls. The exclamation mark is only supported for backward-compatibility with very old versions of VB.
The default member of a Form is (indirectly) the Controls collection.
The bang (!) syntax is used for collection access in VB, and in many cases the compiler makes use of it to early bind things that otherwise would be accessed more slowly through late binding.
Far from deprecated, it is often preferable.
However in this case since the default member of Form objects is [_Default] As Object containing a reference to a Controls As Object instance, there is no particular advantage or disadvantage to this syntax over:
Form5("ProgressBar").Value
I agree that in this case however it is better to more directly access the control as a member of the Form as in:
Form5.ProgressBar.Value
Knowing the difference between these is a matter of actually knowing VB. It isn't simply syntactic though, the two "paths" do different things that get to the same result.
Hopefully this answer offers an explanation rather merely invoking voodoo.

VB6 app controlling Word behaves differently during debug than when compiled

I have a vb6 app that uses Word interop to create a few reports. In the introduction of these reports, there are some instructions in 4 textboxes around an image.
Recently and suddenly the top two textboxes started appearing on the next page, and I can't figure out why. When I step through the code and watch the word document getting built, everything positions itself correctly, however, if I compile the application, the error reappears.
Any suggestions?
Use late-bound calls to Word. This does not mean to remove reference to Microsoft Word Xxx Object Library, just alter your Dims like this
Dim oWord As Object '--- was Word.Application'
Dim oDoc As Object '--- was Word.Document'
...
oDoc.Protect wdAllowOnlyReading '--- keep using enums'
Could it be some 'rounding' difference? For instance if you compare two float point values for equality, the result can subtly depend on the specific compiler/interpreter implementation.
I would like to suggest to trim down your code to the minimum showing the different behaviors. That might clear things up already. If not, please post it here to let us help you.
Maybe you are running the compiled version as a different user than the one running VB when you debug? Maybe this could cause what you are describing, if the two users have some different Word settings.
Is it possible that the compiled version finds a different version of the .dot file?
It may be very helpful if you show the code you use to create the Word document, because then someone here might notice something that can be sensible to moving to a compiled version.
Do you have any code in events that rely on timing, such as Form_Activate, Load, or Unload? I've seen those things behave very differently when stepping through code and when compiled, especially on newer, faster machines.

Cross version line matching

I'm considering how to do automatic bug tracking and as part of that I'm wondering what is available to match source code line numbers (or more accurate numbers mapped from instruction pointers via something like addr2line) in one version of a program to the same line in another. (Assume everything is in some kind of source control and is available to my code)
The simplest approach would be to use a diff tool/lib on the files and do some math on the line number spans, however this has some limitations:
It doesn't handle cross file motion.
It might not play well with lines that get changed
It doesn't look at the information available in the intermediate versions.
It provides no way to manually patch up lines when the diff tool gets things wrong.
It's kinda clunky
Before I start diving into developing something better:
What already exists to do this?
What features do similar system have that I've not thought of?
Why do you need to do this? If you use decent source version control, you should have access to old versions of the code, you can simply provide a link to that so people can see the bug in its original place. In fact the main problem I see with this system is that the bug may have already been fixed, but your automatic line tracking code will point to a line and say there's a bug there. Seems this system would be a pain to build, and not provide a whole lot of help in practice.
My suggestion is: instead of trying to track line numbers, which as you observed can quickly get out of sync as software changes, you should decorate each assertion (or other line of interest) with a unique identifier.
Assuming you're using C, in the case of assertions, this could be as simple as changing something like assert(x == 42); to assert(("check_x", x == 42)); -- this is functionally identical, due to the semantics of the comma operator in C and the fact that a string literal will always evaluate to true.
Of course this means that you need to identify a priori those items that you wish to track. But given that there's no generally reliable way to match up source line numbers across versions (by which I mean that for any mechanism you could propose, I believe I could propose a situation in which that mechanism does the wrong thing) I would argue that this is the best you can do.
Another idea: If you're using C++, you can make use of RAII to track dynamic scopes very elegantly. Basically, you have a Track class whose constructor takes a string describing the scope and adds this to a global stack of currently active scopes. The Track destructor pops the top element off the stack. The final ingredient is a static function Track::getState(), which simply returns a list of all currently active scopes -- this can be called from an exception handler or other error-handling mechanism.

What was the strangest coding standard rule that you were forced to follow? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
When I asked this question I got almost always a definite yes you should have coding standards.
What was the strangest coding standard rule that you were ever forced to follow?
And by strangest I mean funniest, or worst, or just plain odd.
In each answer, please mention which language, what your team size was, and which ill effects it caused you and your team.
I hate it when the use of multiple returns is banned.
reverse indentation. For example:
for(int i = 0; i < 10; i++)
{
myFunc();
}
and:
if(something)
{
// do A
}
else
{
// do B
}
Maybe not the most outlandish one you'll get, but I really really hate when I have to preface database table names with 'tbl'
Almost any kind of hungarian notation.
The problem with hungarian notation is that it is very often misunderstood. The original idea was to prefix the variable so that the meaning was clear. For example:
int appCount = 0; // Number of apples.
int pearCount = 0; // Number of pears.
But most people use it to determine the type.
int iAppleCount = 0; // Number of apples.
int iPearCount = 0; // Number of pears.
This is confusing, because although both numbers are integers, everybody knows, you can't compare apples with pears.
No ternary operator allowed where I currently work:
int value = (a < b) ? a : b;
... because not everyone "gets it". If you told me, "Don't use it because we've had to rewrite them when the structures get too complicated" (nested ternary operators, anyone?), then I'd understand. But when you tell me that some developers don't understand them... um... Sure.
To NEVER remove any code when making changes. We were told to comment all changes. Bear in mind we use source control. This policy didn't last long because developers were in an uproar about it and how it would make the code unreadable.
I once worked under the tyranny of the Mighty VB King.
The VB King was the pure master of MS Excel and VBA, as well as databases (Hence his surname : He played with Excel while the developers worked with compilers, and challenging him on databases could have detrimental effects on your career...).
Of course, his immense skills gave him an unique vision of development problems and project management solutions: While not exactly coding standards in the strictest sense, the VB King regularly had new ideas about "coding standards" and "best practices" he tried (and oftentimes succeeded) to impose on us. For example:
All C/C++ arrays shall start at index 1, instead of 0. Indeed, the use of 0 as first index of an array is obsolete, and has been superseded by Visual Basic 6's insightful array index management.
All functions shall return an error code: There are no exceptions in VB6, so why would we need them at all? (i.e. in C++)
Since "All functions shall return an error code" is not practical for functions returning meaningful types, all functions shall have an error code as first [in/out] parameter.
All our code will check the error codes (this led to the worst case of VBScript if-indentation I ever saw in my career... Of course, as the "else" clauses were never handled, no error was actually found until too late).
Since we're working with C++/COM, starting this very day, we will code all our DOM utility functions in Visual Basic.
ASP 115 errors are evil. For this reason, we will use On Error Resume Next in our VBScript/ASP code to avoid them.
XSL-T is an object oriented language. Use inheritance to resolve your problems (dumb surprise almost broke my jaw open this one day).
Exceptions are not used, and thus should be removed. For this reason, we will uncheck the checkbox asking for destructor call in case of exception unwinding (it took days for an expert to find the cause of all those memory leaks, and he almost went berserk when he found out they had willingly ignored (and hidden) his technical note about checking the option again, sent handfuls of weeks before).
catch all exceptions in the COM interface of our COM modules, and dispose them silently (this way, instead of crashing, a module would only appear to be faster... Shiny!... As we used the über error handling described above, it even took us some time to understand what was really happening... You can't have both speed and correct results, can you?).
Starting today, our code base will split into four branches. We will manage their synchronization and integrate all bug corrections/evolutions by hand.
All but the C/C++ arrays, VB DOM utility functions and XSL-T as OOP language were implemented despite our protests. Of course, over the time, some were discovered, ahem, broken, and abandoned altogether.
Of course, the VB King credibility never suffered for that: Among the higher management, he remained a "top gun" technical expert...
This produced some amusing side effects, as you can see by following the link What is the best comment in source code you have ever encountered?
Back in the 80's/90's, I worked for an aircraft simulator company that used FORTRAN. Our FORTRAN compiler had a limit of 8 characters for variable names. The company's coding standards reserved the first three of them for Hungarian-notation style info. So we had to try and create meaningful variable names with just 5 characters!
I worked at a place that had a merger between 2 companies. The 'dominant' one had a major server written in K&R C (i.e. pre-ANSI). They forced the Java teams (from both offices -- probably 20 devs total) to use this format, which gleefully ignored the 2 pillars of the "brace debate" and goes straight to crazy:
if ( x == y )
{
System.out.println("this is painful");
x = 0;
y++;
}
Forbidden:
while (true) {
Allowed:
for (;;) {
a friend of mine - we'll call him CodeMonkey - got his first job out of college [many years ago] doing in-house development in COBOL. His first program was rejected as 'not complying with our standards' because it used... [shudder!] nested IF statements
the coding standards banned the use of nested IF statements
now, CodeMonkey was not shy and was certain of his abilities, so he persisted in asking everyone up the chain and down the aisle why this rule existed. Most claimed they did not know, some made up stuff about 'readability', and finally one person remembered the original reason: the first version of the COBOL compiler they used had a bug and didn't handle nested IF statements correctly.
This compiler bug, of course, had been fixed for at least a decade, but no one had challenged the standards. [baaa!]
CodeMonkey was successful in getting the standards changed - eventually!
Once worked on a project where underscores were banned. And I mean totally banned. So in a c# winforms app, whenever we added a new event handler (e.g. for a button) we'd have to rename the default method name from buttonName_Click() to something else, just to satisfy the ego of the guy that wrote the coding standards. To this day I don't know what he had against the humble underscore
Totally useless database naming conventions.
Every table name has to start with a number. The numbers show which kind of data is in the table.
0: data that is used everywhere
1: data that is used by a certain module only
2: lookup table
3: calendar, chat and mail
4: logging
This makes it hard to find a table if you only know the first letter of its name.
Also - as this is a mssql database - we have to surround tablenames with square brackets everywhere.
-- doesn't work
select * from 0examples;
-- does work
select * from [0examples];
We were doing a C++ project and the team lead was a Pascal guy.
So we had a coding standard include file to redefine all that pesky C and C++ syntax:
#define BEGIN {
#define END }
but wait there's more!
#define ENDIF }
#define CASE switch
etc. It's hard to remember after all this time.
This took what would have been perfectly readable C++ code and made it illegible to anyone except the team lead.
We also had to use reverse Hungarian notation, i.e.
MyClass *class_pt // pt = pointer to type
UINT32 maxHops_u // u = uint32
although oddly I grew to like this.
At a former job:
"Normal" tables begin with T_
"System" tables (usually lookups) begin with TS_ (except when they don't because somebody didn't feel like it that day)
Cross-reference tables begin with TSX_
All field names begin with F_
Yes, that's right. All of the fields, in every single table. So that we can tell it's a field.
A buddy of mine encountered this rule while working at a government job. The use of ++ (pre or post) was completely banned. The reason: Different compilers might interpret it differently.
Half of the team favored four-space indentation; the other half favored two-space indentation.
As you can guess, the coding standard mandated three, so as to "offend all equally" (a direct quote).
Not being able to use Reflection as the manager claimed it involved too much 'magic'.
The very strangest one I had, and one which took me quite some time to overthrow, was when the owner of our company demanded that our new product be IE only. If it could work on FireFox, that was OK, but it had to be IE only.
This might not sound too strange, except for one little flaw. All of the software was for a bespoke server software package, running on Linux, and all client boxes that our customer was buying were Linux. Short of trying to figure out how to get Wine (in those days, very unreliable) up and running on all of these boxes and seeing if we could get IE running and training their admins how to debug Wine problems, it simply wasn't possible to meet the owner's request. The problem was that he was doing the Web design and simply didn't know how to make Web sites compliant with FireFox.
It probably won't shock you to know that that our company went bankrupt.
Using generic numbered identifier names
At my current work we have two rules which are really mean:
Rule 1: Every time we create a new field in a database table we have to add additional reserve fields for future use. These reserve fields are numbered (because no one knows which data they will hold some day) The next time we need a new field we first look for an unused reserve field.
So we end up with with customer.reserve_field_14 containing the e-mail address of the customer.
At one day our boss thought about introducing reserve tables, but fortunatly we could convince him not to do it.
Rule 2: One of our products is written in VB6 and VB6 has a limit of the total count of different identifier names and since the code is very large, we constantly run into this limit. As a "solution" all local variable names are numbered:
Lvarlong1
Lvarlong2
Lvarstr1
...
Although that effectively circumvents the identifier limit, these two rules combined lead to beautiful code like this:
...
If Lvarbool1 Then
Lvarbool2 = True
End If
If Lvarbool2 Or Lvarstr1 <> Lvarstr5 Then
db.Execute("DELETE FROM customer WHERE " _
& "reserve_field_12 = '" & Lvarstr1 & "'")
End If
...
You can imagine how hard it is to fix old or someone else's code...
Latest update: Now we are also using "reserve procedures" for private members:
Private Sub LSub1(Lvarlong1 As Long, Lvarstr1 As String)
If Lvarlong1 >= 0 Then
Lvarbool1 = LFunc1(Lvarstr1)
Else
Lvarbool1 = LFunc6()
End If
If Lvarbool1 Then
LSub4 Lvarstr1
End If
End Sub
EDIT: It seems that this code pattern is becoming more and more popular. See this The Daily WTF post to learn more: Astigmatism :)
Back in my C++ days we were not allowed to use ==,>=, <=,&&, etc. there were macros for this ...
if (bob EQ 7 AND alice LEQ 10)
{
// blah
}
this was obviously to deal with the "old accidental assignment in conditional bug", however we also had the rule "put constants before variables", so
if (NULL EQ ptr); //ok
if (ptr EQ NULL); //not ok
Just remembered, the simplest coding standard I ever heard was "Write code as if the next maintainer is a vicious psychopath who knows where you live."
Hungarian notation in general.
I've had a lot of stupid rules, but not a lot that I considered downright strange.
The sillyiest was on a NASA job I worked back in the early 90's. This was a huge job, with well over 100 developers on it. The experienced developers who wrote the coding standards decided that every source file should begin with a four letter acronym, and the first letter had to stand for the group that was responsible for the file. This was probably a great idea for the old FORTRAN 77 projects they were used to.
However, this was an Ada project, with a nice hierarchal library structure, so it made no sense at all. Every directory was full of files starting with the same letter, followed by 3 more nonsense leters, an underscore, and then part of the file name that mattered. All the Ada packages had to start with this same five-character wart. Ada "use" clauses were not allowed either (arguably a good thing under normal circumstances), so that meant any reference to any identifier that wasn't local to that source file also had to include this useless wart. There probably should have been an insurrection over this, but the entire project was staffed by junior programmers and fresh from college new hires (myself being the latter).
A typical assignment statement (already verbose in Ada) would end up looking something like this:
NABC_The_Package_Name.X := NABC_The_Package_Name.X +
CXYZ_Some_Other_Package_Name.Delta_X;
Fortunately they were at least enlightened enough to allow us more than 80 columns! Still, the facility wart was hated enough that it became boilerplate code at the top of everyone's source files to use Ada "renames" to get rid of the wart. There'd be one rename for each imported ("withed") package. Like this:
package Package_Name renames NABC_Package_Name;
package Some_Other_Package_Name renames CXYZ_Some_Other_Package_Name;
--// Repeated in this vein for an average of 10 lines or so
What the more creative among us took to doing was trying to use the wart to make an acutally sensible (or silly) package name. (I know what you are thinking, but explitives were not allowed and shame on you! That's disgusting). For example, I was in the Common code group, and I needed to make a package to interface with the Workstation group. After a brainstorming session with the Workstation guy, we decided to name our packages so that someone needing both would have to write:
with CANT_Interface_Package;
with WONT_Interface_Package;
When I started working at one place, and started entering my code into the source control, my boss suddenly came up to me, and asked me to stop committing so much. He told me it is discouraged to do more than 1 commit per-day for a developer because it litters the source control. I simply gaped at him...
Later I understood that the reason he even came up to me about it is because the SVN server would send him (and 10 more high executives) a mail for each commit someone makes. And by littering the source control I guessed he ment his mailbox.
Doing all database queries via stored procedures in Sql Server 2000. From complex multi-table queries to simple ones like:
select id, name from people
The arguments in favor of procedures were:
Performance
Security
Maintainability
I know that the procedure topic is quite controversial, so feel free to score my answer negatively ;)
There must be 165 unit tests (not necessarily automated) per 1000 lines of code. That works out at one test for roughly every 8 lines.
Needless to say, some of the lines of code are quite long, and functions return this pointers to allow chaining.
We had to sort all the functions in classes alphabetically, to make them "easier to find".
Never mind the ide had a drop down. That was too many clicks.
(same tech lead wrote an app to remove all comments from our source code).
In 1987 or so, I took a job with a company that hired me because I was one of a small handful of people who knew how to use Revelation. Revelation, if you've never heard of it, was essentially a PC-based implementation of the Pick operating system - which, if you've never heard of it, got its name from its inventor, the fabulously-named Dick Pick. Much can be said about the Pick OS, most of it good. A number of supermini vendors (Prime and MIPS, at least) used Pick, or their own custom implementations of it.
This company was a Prime shop, and for their in-house systems they used Information. (No, that was really its name: it was Prime's implementation of Pick.) They had a contract with the state to build a PC-based system, and had put about a year into their Revelation project before the guy doing all the work, who was also their MIS director, decided he couldn't do both jobs anymore and hired me.
At any rate, he'd established a number of coding standards for their Prime-based software, many of which derived from two basic conditions: 1) the use of 80-column dumb terminals, and 2) the fact that since Prime didn't have a visual editor, he'd written his own. Because of the magic portability of Pick code, he'd brought his editor down into Revelation, and had built the entire project on the PC using it.
Revelation, of course, being PC-based, had a perfectly good full-screen editor, and didn't object when you went past column 80. However, for the first several months I was there, he insisted that I use his editor and his standards.
So, the first standard was that every line of code had to be commented. Every line. No exceptions. His rationale for that was that even if your comment said exactly what you had just written in the code, having to comment it meant you at least thought about the line twice. Also, as he cheerfully pointed out, he'd added a command to the editor that formatted each line of code so that you could put an end-of-line comment.
Oh, yes. When you commented every line of code, it was with end-of-line comments. In short, the first 64 characters of each line were for code, then there was a semicolon, and then you had 15 characters to describe what your 64 characters did. In short, we were using an assembly language convention to format our Pick/Basic code. This led to things that looked like this:
EVENT.LIST[DATE.INDEX][-1] = _ ;ADD THE MOST RECENT EVENT
EVENTS[LEN(EVENTS)] ;TO THE END OF EVENT LIST
(Actually, after 20 years I have finally forgotten R/Basic's line-continuation syntax, so it may have looked different. But you get the idea.)
Additionally, whenever you had to insert multiline comments, the rule was that you use a flower box:
************************************************************************
** IN CASE YOU NEVER HEARD OF ONE, OR COULDN'T GUESS FROM ITS NAME, **
** THIS IS A FLOWER BOX. **
************************************************************************
Yes, those closing asterisks on each line were required. After all, if you used his editor, it was just a simple editor command to insert a flower box.
Getting him to relent and let me use Revelation's built-in editor was quite a battle. At first he was insistent, simply because those were the rules. When I objected that a) I already knew the Revelation editor b) it was substantially more functional than his editor, c) other Revelation developers would have the same perspective, he retorted that if I didn't train on his editor I wouldn't ever be able to work on the Prime codebase, which, as we both knew, was not going to happen as long as hell remained unfrozen over. Finally he gave in.
But the coding standards were the last to go. The flower-box comments in particular were a stupid waste of time, and he fought me tooth and nail on them, saying that if I'd just use the right editor maintaining them would be perfectly easy. (The whole thing got pretty passive-aggressive.) Finally I quietly gave in, and from then on all of the code I brought to code reviews had his precious flower-box comments.
One day, several months into the job, when I'd pretty much proven myself more than competent (especially in comparison with the remarkable parade of other coders that passed through that office while I worked there), he was looking over my shoulder as I worked, and he noticed I wasn't using flower-box comments. Oh, I said, I wrote a source-code formatter that converts my comments into your style when I print them out. It's easier than maintaining them in the editor. He opened his mouth, thought for a moment, closed it, went away, and we never talked about coding standards again. Both of our jobs got easier after that.
At my first job, all C programs, no matter how simple or complex, had only four functions. You had the main, which called the other three functions in turn. I can't remember their names, but they were something along the lines of begin(), middle(), and end(). begin() opened files and database connections, end() closed them, and middle() did everything else. Needless to say, middle() was a very long function.
And just to make things even better, all variables had to be global.
One of my proudest memories of that job is having been part of the general revolt that led to the destruction of those standards.
An externally-written C coding standard that had the rule 'don't rely on built in operator precedence, always use brackets'
Fair enough, the obvious intent was to ban:
a = 3 + 6 * 2;
in favour of:
a = 3 + (6 * 2);
Thing was, this was enforced by a tool that followed the C syntax rules that '=', '==', '.' and array access are operators. So code like:
a[i].x += b[i].y + d - 7;
had to be written as:
((a[i]).x) += (((b[i]).y + d) - 7);

How do you feel about code folding? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
For those of you in the Visual Studio environment, how do you feel about wrapping any of your code in #regions? (or if any other IDE has something similar...)
9 out of 10 times, code folding means that you have failed to use the SoC principle for what its worth.
I more or less feel the same thing about partial classes. If you have a piece of code you think is too big you need to chop it up in manageable (and reusable) parts, not hide or split it up.It will bite you the next time someone needs to change it, and cannot see the logic hidden in a 250 line monster of a method.
Whenever you can, pull some code out of the main class, and into a helper or factory class.
foreach (var item in Items)
{
//.. 100 lines of validation and data logic..
}
is not as readable as
foreach (var item in Items)
{
if (ValidatorClass.Validate(item))
RepositoryClass.Update(item);
}
My $0.02 anyways.
This was talked about on Coding Horror.
My personal belief is that is that they are useful, but like anything in excess can be too much.
I use it to order my code blocks into:
Enumerations
Declarations
Constructors
Methods
Event Handlers
Properties
Sometimes you might find yourself working on a team where #regions are encouraged or required. If you're like me and you can't stand messing around with folded code you can turn off outlining for C#:
Options -> Text Editor -> C# -> Advanced Tab
Uncheck "Enter outlining mode when files open"
I use #Region to hide ugly and useless automatically generated code, which really belongs in the automatically generated part of the partial class. But, when working with old projects or upgraded projects, you don't always have that luxury.
As for other types of folding, I fold Functions all the time. If you name the function well, you will never have to look inside unless you're testing something or (re-)writing it.
While I understand the problem that Jeff, et. al. have with regions, what I don't understand is why hitting CTRL+M,CTRL+L to expand all regions in a file is so difficult to deal with.
I use Textmate (Mac only) which has Code folding and I find it really useful for folding functions, I know what my "getGet" function does, I don't need it taking up 10 lines of oh so valuable screen space.
I never use it to hide a for loop, if statement or similar unless showing the code to someone else where I will hide code they have seen to avoid showing the same code twice.
I prefer partial classes as opposed to regions.
Extensive use of regions by others also give me the impression that someone, somewhere, is violating the Single Responsibility Principle and is trying to do too many things with one object.
#Tom
Partial classes are provided so that you can separate tool auto-generated code from any customisations you may need to make after the code gen has done its bit. This means your code stays intact after you re-run the codegen and doesn't get overwritten. This is a good thing.
I'm not a fan of partial classes - I try to develop my classes such that each class has a very clear, single issue for which it's responsible. To that end, I don't believe that something with a clear responsibility should be split across multiple files. That's why I don't like partial classes.
With that said, I'm on the fence about regions. For the most part, I don't use them; however, I work with code every day that includes regions - some people go really heavy on them (folding up private methods into a region and then each method folded into its own region), and some people go light on them (folding up enums, folding up attributes, etc). My general rule of thumb, as of now, is that I only put code in regions if (a) the data is likely to remain static or will not be touched very often (like enums), or (b) if there are methods that are implemented out of necessity because of subclassing or abstract method implementation, but, again, won't be touched very often.
Regions must never be used inside methods. They may be used to group methods but this must be handled with extreme caution so that the reader of the code does not go insane. There is no point in folding methods by their modifiers. But sometimes folding may increase readability. For e.g. grouping some methods that you use for working around some issues when using an external library and you won't want to visit too often may be helpful. But the coder must always seek for solutions like wrapping the library with appropriate classes in this particular example. When all else fails, use folding for improving readibility.
This is just one of those silly discussions that lead to nowhere. If you like regions, use them. If you don't, configure your editor to turn them off. There, everybody is happy.
I generally find that when dealing with code like Events in C# where there's about 10 lines of code that are actually just part of an event declaration (the EventArgs class the delegate declaration and the event declaration) Putting a region around them and then folding them out of the way makes it a little more readable.
Region folding would be fine if I didn't have to manually maintain region groupings based on features of my code that are intrinsic to the language. For example, the compiler already knows it's a constructor. The IDE's code model already knows it's a constructor. But if I want to see a view of the code where the constructors are grouped together, for some reason I have to restate the fact that these things are constructors, by physically placing them together and then putting a group around them. The same goes for any other way of slicing up a class/struct/interface. What if I change my mind and want to see the public/protected/private stuff separated out into groups first, and then grouped by member kind?
Using regions to mark out public properties (for example) is as bad as entering a redundant comment that adds nothing to what is already discernible from the code itself.
Anyway, to avoid having to use regions for that purpose, I wrote a free, open source Visual Studio 2008 IDE add-in called Ora. It provides a grouped view automatically, making it far less necessary to maintain physical grouping or to use regions. You may find it useful.
I think that it's a useful tool, when used properly. In many cases, I feel that methods and enumerations and other things that are often folded should be little black boxes. Unless you must look at them for some reason, their contents don't matter and should be as hidden as possible. However, I never fold private methods, comments, or inner classes. Methods and enums are really the only things I fold.
My approach is similar to a few others here, using regions to organize code blocks into constructors, properties, events, etc.
There's an excellent set of VS.NET macros by Roland Weigelt available from his blog entry, Better Keyboard Support for #region ... #endregion. I've been using these for years, mapping ctrl+. to collapse the current region and ctrl++ to expand it. Find that it works a lot better that the default VS.NET functionality which folds/unfolds everything.
I personally use #Regions all the time. I find that it helps me to keep things like properties, declarations, etc separated from each other.
This is probably a good answer, too!
Coding Horror
Edit: Dang, Pat beat me to this!
The Coding Horror article actual got me thinking about this as well.
Generally, I large classes I will put a region around the member variables, constants, and properties to reduce the amount of text I have to scroll through and leave everything else outside of a region. On forms I will generally group things into "member variables, constants, and properties", form functions, and event handlers. Once again, this is more so I don't have to scroll through a lot of text when I just want to review some event handlers.
I prefer #regions myself, but an old coworker couldn't stand to have things hidden. I understood his point once I worked on a page with 7 #regions, at least 3 of which had been auto-generated and had the same name, but in general I think they're a useful way of splitting things up and keeping everything less cluttered.
I really don't have a problem with using #region to organize code. Personally, I'll usually setup different regions for things like properties, event handlers, and public/private methods.
Eclipse does some of this in Java (or PHP with plugins) on its own. Allows you to fold functions and such. I tend to like it. If I know what a function does and I am not working on it, I dont need to look at it.
Emacs has a folding minor mode, but I only fire it up occasionally. Mostly when I'm working on some monstrosity inherited from another physicist who evidently had less instruction or took less care about his/her coding practices.
Using regions (or otherwise folding code) should have nothing to do with code smells (or hiding them) or any other idea of hiding code you don't want people to "easily" see.
Regions and code folding is really all about providing a way to easily group sections of code that can be collapsed/folded/hidden to minimize the amount of extraneous "noise" around what you are currently working on. If you set things up correctly (meaning actually name your regions something useful, like the name of the method contained) then you can collapse everything except for the function you are currently editing and still maintain some level of context without having to actually see the other code lines.
There probably should be some best practice type guidelines around these ideas, but I use regions extensively to provide a standard structure to my code files (I group events, class-wide fields, private properties/methods, public properties/methods). Each method or property also has a region, where the region name is the method/property name. If I have a bunch of overloaded methods, the region name is the full signature and then that entire group is wrapped in a region that is just the function name.
I personally hate regions. The only code that should be in regions in my opinion is generated code.
When I open file I always start with Ctrl+M+O. This folds to method level. When you have regions you see nothing but region names.
Before checking in I group methods/fields logically so that it looks ok after Ctrl+M+O.
If you need regions you have to much lines in your class. I also find that this is very common.
region ThisLooksLikeWellOrganizedCodeBecauseIUseRegions
// total garbage, no structure here
endregion
Enumerations
Properties
.ctors
Methods
Event Handlers
That's all I use regions for. I had no idea you could use them inside of methods.
Sounds like a terrible idea :)

Resources