Every once in a blue moon, I hear someone ask what the "proper" coding style is for REALbasic. The answer is -- there is no one proper way.
However, there is my way. :-P
So here's the personal coding style I try to adhere to in my own projects.
1) All project item names are title-cased (ThisIsMyClassName) and contain no underscores.
2) Project item names are meaningful. For items like pictures, sounds, etc, the name describes the item (ButtonIcon, Klaxon). Class, interface and module names are descriptive nouns (FindWindow, KeyDownDelegate, Strings).
3) Property names are prefixed with a "m" and are otherwise title-cased, descriptive nouns (mCurrentDocument). Also, all properties have the most-restrictive scope possible.
4) All constants are prefixed with a "k" and are otherwise title-cased, descriptive nouns (kApple, kOrange). This also applies to enumeration members.
5) All event definitions are title-cased (without a prefix) and are descriptive active verbs (Open, Close, MouseDown).
6) All method names are title-cased (without a prefix) and are descriptive active verbs (CloseFile, HitBall). The parameters are all mixed-case, descriptive nouns (leftPosition, theFile). Methods have the most restrictive scope possible.
7) All code is commented using the // token. ' is reserved for temporary removal of code, and isn't used for permanent description. All code is commented, regardless of how "obvious" its use is. Because after a year, almost no code is obvious to anyone -- even the original author.
8) Static local variables are prefixed with an "s" and are otherwise title-cased, desciptive nouns (sInstance, sLock).
9) Non-static local variables are mixed-case (without a prefix), descriptive nouns (theFile, leftPosition). They are declared with the most local scope, as close to the code using them as possible. This means that a local variable used only in an if block is declared inside of that if block. In the case of for loops, I declare the loop counter as a part of the loop construct itself. As in: for i as Integer = 0 to 10
10) All keywords are lower-cased. So it's "for", "next" and "return" instead of "For", "Next" and "Return"
11) All method calls use parenthesis when invoking the method, unless there are no parameters, including sub calls. So if you have the methods: Sub Foo( bar as String ), Function Bar( i as Integer ) as String and Sub Test(), they would be called like: Foo( bar ), Bar( i ), Test
12) Bracket all tokens with spaces. Examples:
[rbcode]
Dim i(-1) as Integer // Wrong
Dim i( -1 ) as Integer // Right
i=1+1 // Wrong
i = 1 + 1 // Right
Foobar(1) // Wrong
Foobar( 1 ) // Right
while foo
while foo < bar // Right
wend[/rbcode]
I think that about covers the coding standards that I use for my own projects. Obviously, there are going to be times I vary from this (for instance, sometimes I'll use a sentence instead of a noun with local variables, such as sBeenCheckedBefore as Boolean). But this is a pretty good gist of what I try to follow. Most of it is subconcious at this point.
If I missed other areas and you're just dying to know what my personal coding style says about them, feel free to ask.
And just so we're clear -- there is no one right way to code. Use what works for you, but be consistent. That's the real key to a coding style. This happens to work well for me, so I use it this way. But I don't expect it would work well for everyone (for instance, a Microsoft programmer would shudder at the lack of Hungarian notation).
I learned from Jonathan not long ago that RS' internal style uses no spaces for array indexing and uses spaces for actual parameters, like this:
method call:
x = foo( 1, 2, 3 )
array access:
x = arr(1)
While I find the spacing ugly (I rather like to follow the style I learned in school for regular text), I think that if someone wants to adopt the "ugly" spacing rules you propose, the RS' rule for differentiating between arrays and parameters is quite useful, though.
Besides, what kind of mind is it that goes around calling styles right and wrong, instead of good and bad? :)
Hi Aaron!
Your code style pretty much matches mine. I agree wholeheartedly with the addition of parentheses for the parameters of all method calls and spaces around all operators and between parentheses. It just makes the code easier to read.
The only code style that I've vacillated on is using the "m" prefix on properties. Theoretically the _user_ of the code should be oblivious to whether a call is to a property or a method. But, like I said, I sometimes change my mind and go right back to using it.
So very close to my style :) But I never put parens around arguments to subroutines. And I never put spaces between an argument and a paren (in an argument list). And, another thing I found useful, is to prefix method arguments with a lower-case 'a'. So it would be: sub Method(aArg1 as Integer, aArg2 as String). That's to distinguish them from local variables, which, as you say, have no prefix.
@TT & @Will -- yes, those are good ways to differentiate between things. Not a bad idea. I tend to like the spacing of arrays because it's consistent with everything else. And since an array is usually a noun, and a method is usually a verb, I don't have too much trouble figuring out which is which.
@Scott -- I only use the m for non-public properties. I usually avoid public properties at all costs.
@TT -- I dunno, but people ask it in those terms. :-)
I use a p prefix for parameters and m for members. Local variables don't have prefixes for me. There usually aren't very many so there's not too much use in prefixing with a type identifier.
And I'm a no spacer except in confusing circumstances. Definitely dim arr(-1) as Integer, CallSub(a, b, c), if ( LikesRB(crazyGuy || bananaGuy) and (ImReallyBored || IHateSchool) ) then
Aaron,
It's good to hear alternative styles. Here are a couple things I do differently:
1. Prefix private/protected variables with "my" instead of "m". Makes it more human-readable, I think.
2. No space after the () in a method or subroutine invocation. (By the way, parens are tokens too ;)
3. We used to distinguish between internal constants and localizable constants by using "x" for internal and "k" for localizable. But this isn't strictly necessary anymore, with the invention of the dynamic constant :)
4. I like to leave out the parens for subroutines of a single parameter, and use them otherwise. I find "Foo x, y" to be weird on the eyes, but "Foo(x)" looks silly when "Foo x" will do.
Here's some additions I try to follow and which I often see done _wrong_ (sic):
1. functions returning a boolean should be prefixed with "is" or "can" or "has", like this:
if IsAsyncKeyDown() then
2. a method should only be prefixed by Get if it has ByRef parms where it stores the result in, but not if it returns the result as a function:
if GetNextValue (theValue) then
but:
theValue = NextValue ()
Addendum (darn, why can't we edit our comments? :)
The GetNextValue example above did two things at once. More to the point would be these:
GetNextValue (theValue) // a method instead of the "NextValue()" function
and:
if FetchValue (theValue) then
this one returns true if a value was retrieved from some list or pool, and false if no data was available.
My point is, similar to Aaron's, that functions and methods should be named with verbs and other grammatical items so that they become proper sentences when used. Using "is" in boolean functions (and also in bool vars) is a major factor in this, IMO.
I also use quite the same coding style, but use always Title Case for the keywords.
To differenciate arrays I always prefix them with "arr".
And what about naming the controls? Do you prefix or suffix the names with a control abbreviation?
I often use a prefix like pbName (for PushButtons). But for databases I use instead a suffix, like NameDB.
@Carlos -- great question. I usually try to include something about the control in the name, but it's not a set standard. So if I have a ListBox which displays IP addresses, I'd name it IPAddressList. If I have an EditField which takes a password, I'd name it PasswordField.
But I do try to name every control, even if it's not "used." GroupBoxes and StaticTexts get descriptive names as well.
Yeah I dont like the spaces :P
Actually, Microsoft has two different camps - C/C++ style and .NET style. In the first, classes are like CShape, variables are strName, in the latter, Classes are Shape and variables are just name or _name, etc.
There are so many different ways to skin a cat, so I think a mix of all styles is right in some way shape or form.
Close to mine, but not quite :-)
You said, "All keywords are lower-cased", and then proceded to say "Dim i as Integer."
I would argue for "dim i as integer" -- dim being a keyword, integer being a data type (not a class).
Sub DoFoo( param as string, otherThing as Date )
Methods are TitleCased, param names are titleCased (first letter lowercase), and class names are Uppercased.
Spaces around all punctuation: doFoo( "bar", new Date() )
dim i as integer = ( 2 + 3 ) * 4
Class names (including controls and windows) are descriptive nouns. The initial letter of class, control, and method names is uppercase, while the first letter of parameters, local variables, and properties is lowercase.
Non-public properties are prefixed with "m," but public properties follow the same rules as local variables.
I think that about covers it.
@Aaron: I also used that kind of style (suffix) for naming the controls, but because I often needed to go back to the window editor to find out what was the name of a control (my memory is not the same) I decided to take advantage of the RB’s autocomplete and prefix most of the control names with an abbreviation - this way, if I don’t remember the name of a control that is an EditField I just type “ef†and RB shows me all the EditField controls.
I would think that only the old school (VB6 and earlier) programmers would shudder at the lack of hungarian notation. Once .Net was released the consensus was to switch to (what I heard some [Dan Applebaum] call) Pascal Notation (which you call TitleCase). I think the term TitleCase makes more sense. Even at one of MS's introductory conferences the speaker suggested dumping Hungarian notation since the need to identify the type of variable declared was no longer important (the mouse rollover balloons killed the need). I attended that conference with a friend who wrote advanced VB books for the Unleashed series and he shuddered at the thought of not using hungarian notation :)
I also adhere to Thomas' Is/Get style as well. I think that has sunk into my subconscious through MS's extensive use of it. Just kind of makes sense.
@Carlos -- that's the beauty of style guidelines. Pick what works and stick with it and you won't go wrong (usually). Some day, I'll probably have to start prefixing controls too - I am getting up there in years faster than I'd like. ;-)
@Steve -- I agree, Hungarian notation for some of us is almost second nature. It's hard *not* to write lpstrFoobar or ccSize sometimes!
Not sure I have much of a style, but one thing I do is to put a ¿ at the end of anything Boolean (I'd use a ?, but the compiler won't take that). Serves the same function as the Is, but I grew up in old-fashioned BASIC where the only type-related character ($tring) was a postfix, and prefixing anything was bad because even though you could use long variable names, they had to be unique when truncated to 2 characters. (Also, having it at the end eliminates any thought of adding an "=True"--a construction that just bugs me no end).
Similarly, the ¡ (inverted bang) goes at the end of boolean setters--other setters are marked "giveProperty" and corresponding getters "askProperty". Only one case where I attach any significance to spacing--= gets no spaces if it's a comparison, but a space on each side when it's an assignment.
What are your notations for GUI objects? This is the only case where I find hungarian notation useful. Button42, Window3 ...yech!
I can care less how and when you put spaces, but the optional parens and preference for their absence kill me. When scanning through the code I double-take thinking I've run across a mis-placed cursor drop.
@Dean -- I don't like numbers in any variable names, including controls. Hungarian notation would work well for UI controls; I just happen to not use it.
As for the optional parens, that's the one that catches me the absolute most. Foo x, y just looks *wrong* to me, and Foo( x, y ) looks proper. Don't ask me why I prefer Foo over Foo() though, cuz I have no logical answer to that. ;-)
Foo x, y looks wrong to me too. Parenthesis give my eyes a natural way to break up the statement and tell me what is going on - a function call. I used to use Foo, but now I prefer Foo(). Again, it gives me more information at a glance. I don't have to mouse over it to tell what it is (control? window? function? property? local variable?).
I tend to use suffixes for control names: NameField, CandyFlavorRadio, FavoriteColorPopup, etc. That way I can half-forget the name of the control, type the beginning of the descriptive name (something about "name"...), and then the suffix tells me whether I have the right control.
I would use Foo instead of Foo() for flexibility.
For example, when computed properties came along it was a cinch to move some of my code from methods into computed properties because I hadn't used parens.
It's a bit strange for me to be saying that as I (like many) come from a background where Foo() was the only option, but I've moved on.