Since it came up, and I've just had some strong coffee, here's my personal coding conventions* for OOABL.
Code casing
Lower case, baby, yeah (sounds good when you Austin Powers-ify it)
Property names
Properties names should be a name only, with no indication of data type. They should be PUBLIC as far as possible, although they can be PROTECTED. They should never be PRIVATE.
Member variables
These should be of the form m, where the datatype corresponds to a value in the table below.
Data type Name
o Object
e Progress.Lang.Error
c Character, Longchar
d Decimal
i Integer, Int64
t Date, Datetime, Datetime-tz
r Raw, Rowid
l Logical
Member variables should always be PRIVATE or PROTECTED; publically accessible members should be made properties. The exception to this is if they are used as pseudo-enums.
Constant or static member variables
The variable names should be descriptive and uppercase. Words should be separated by underscores. For example,
Method-local variables
Variables defined within methods should have the form , where the data type matches the table above.
Method names
Method names should describe the function of the method, and should be in CamelCase (1st letter in caps). For instance, GetInstance().
Access levels
As a rule of thumb, methods and members should be PUBLIC or PROTECTED. The protected status allows for overloading; PRIVATE should be used only when there’s a good reason to keep something explicitly within a class.
Package names
Package names should be in CamelCase (1st letter in caps).
For example,
OpenEdge.Reference.MyApplication.
Class names
Class names should be in CamelCase.
Use of the USING statement
Using USING is strongly recommended – it makes code more readable and makes refactoring much easier.
Emulating enums
Enums can be emulated by using integer variables and static public variables. This is the exception to the rule above.
I'm still not sure whether I like the member names for enums to be upper case (like static/constant variables) or camel, like properties.
Temp-table and dataset names
Temp-tables are tt.
Have at it!
-- peter
applies. Also, I'm calling them "conventions" rather than standards because I think that's more flexible-sounding than "standards"
My variable naming conventions are here http://www.cintegrity.com/node/65 . I haven't updated them yet for some of the new issues like statics, but they are fairly obvious extensions of what is there.
Shouldn't this be on the OO forum?
So now you are trying to hurt your self.
You have already read my oppinion on lower casing key words.
Two interesting things could you please explain a bit more about them?
Constant or static member variables
The variable names should be descriptive and
uppercase. Words should be separated by underscores.
For example,
What's so similar about Constanc or static member variables? I've seen that concention a lot for constant variables (like in C header files). But static?
Temp-table and dataset names
Temp-tables are tt, where the Descriptor
is a single noun. Can also be e.
Dataset are named ds.
Why just a single noun? What's wrong with eOrderLine or eCustomerEmployee (to distinguis from eEmployee)?
Why no statement on singular or plural here?
Package names
Package names should be in CamelCase (1st letter in
caps).
You deserve a great weekend for that! No com.progress...... in ABL code.
No com.progress...... in ABL code.
Not sure if you mean what you seem to be saying, but if so, I disagree. I have been doing all of my stuff under com.cintegrity below which is application and package. This makes it much easier to use stuff from other people without stepping all over people.
No com.progress...... in ABL code.
I like Peter's way of using the .NET style of namespaces (like OpenEdge.Application...) rather than com.progress....
That's all.
So now you are trying to hurt your self.
Like I said, strong coffee.
Constant or static member variables
The variable names should be descriptive and
uppercase. Words should be separated by
underscores.
For example,
What's so similar about Constanc or static member
variables? I've seen that concention a lot for
constant variables (like in C header files). But
static?
I think I took this convention from the Java world; it makes it clear that the value won't (or shouldn't) change (until the ABL introduces a CONSTANT er, constant, keyword, the values will be able to change).
Having said that, I think I should amend my convention to state that members that are intended to be constants should have the UPPER_CASE_NAME convention; it's not really the fact that they're statics that defines that. My pseudo-enums use statics and as I noted, I'm somewhat conflicted as to whether they should have upper or camel cased names.
Why just a single noun? What's wrong with eOrderLine
or eCustomerEmployee (to distinguis from eEmployee)?
Why no statement on singular or plural here?
Sorry, I meant singular, and not single. Sometimes the words just don't want to come ...
You deserve a great weekend for that! No
com.progress...... in ABL code.
I thought you might appreciate the more .NET-like OpenEdge.MyApp.MyModule notation
-- peter
Shouldn't this be on the OO forum?
Indeed. I'll get it moved over there.
-- peter
The problem I have with not using the com.cintegrity part on the top is the issues in combining components from multiple sources. If I write some stuff that starts with AutoEdge and you write some stuff with AutoEdge, no telling how they might interact.
Having said that, I think I should amend my convention to state that members that are intended to be constants should have the UPPER_CASE_NAME convention; it's not really the fact that they're statics that defines that. My pseudo-enums use statics and as I noted, I'm somewhat conflicted as to whether they should have upper or camel cased names.
Having not asked myself this question yet ... which shows you how much coding I have been doing lately, my first instinct is to think that I would cover these by the scope prefix in my system.
That's why my AutoEdge stuff would be in
and your's might be in
Member variables
These should be of the form m, where
the datatype corresponds to a value in the table
below.
Data type Name
o Object
e Progress.Lang.Error
c Character, Longchar
d Decimal
i Integer, Int64
t Date, Datetime, Datetime-tz
r Raw, Rowid
l Logical
Just for interests' sake, ideally, I'd like to not use a prefix at all. C# or Java typically use the class name, but with a lowercase first letter: def var myClass as MyClass. Since the ABL is case-insensitive, myClass = MyClass = Myclass = myclass. Unfortunately, this can cause problems in certain cases, and working on the theory that a convention is a convention, an "o" prefix it is.
The "problematic", documented behaviour is:
-- peter
That I could handle ... but I don't know that I want to give any edge to .NET. Seems more cross-platform standard to follow Java in this sense.
That I could handle ... but I don't know that I want
to give any edge to .NET. Seems more cross-platform
standard to follow Java in this sense.
po-TAY-to, po-TAH-to to me.
The GUI for .NET objects use .NET, so I tend to follow that standard. The built-ins also follow it (Progress.Lang.Object etc), so it's consistent with that too.
But the important thing is that you're consistent throughout your app.
-- peter
Yeah, but I feel like I am being clubbed into submission and I tend not to like that. I expect the Progress built ins are like that exactly because 10.2A was ABL GUI for .NET. If it had been for Java, it probably would have been com.progress. And, yeah, people are passionate about .NET and all, but there is the rest of the world.
It is like this 25 year fight against default uppercase keywords. Yuck. Now, finally, there are some reasonable tools to get away from it, but remember 10.1A where there were a bunch of templates you couldn't even replace?
Package names
Package names should be in CamelCase (1st letter in
caps).
For example,
OpenEdge.Reference.MyApplication.
Class names
Class names should be in CamelCase.
After a lot of discussion and careful consideration, we have decided for all lowercase because of deployment on *nix. That is the only rule that guarantees preventing deployment problems.
We have briefly discussed the possibility of using camelcase on client code, but again, the only rule that guarantees preventing deployment problems is all lowercase.
So in our case, this rule applies to anything that ends up on disk.
Once upon a time, I thought that was an annoying, but reasonable limitation ... although at the time I focused more on DOS's inability to tell the difference than on *nix's ability to distinguish. Now, frankly, I think it is more a question of imposing style guides on one's code. There is no actual deployment problem with mixed case file names unless you do something stupid like name two files in the same location the same name in different case and then try to deploy on an OS that can't tell the difference. Other than that, is is just having to be consistent.
There is no actual deployment problem with mixed case file names unless you do something stupid like name two files in the same location the same name in different case and then try to deploy on an OS that can't tell the difference. Other than that, is is just having to be consistent.
Deployment problems - no. Being consistent - yes, particularly on remembering where the camel casing was.
There is no actual deployment problem with mixed
case file names unless you do something stupid like
name two files in the same location the same name in
different case and then try to deploy on an OS that
can't tell the difference. Other than that, is is
just having to be consistent.
Actually the other way around. The other day we had the problem that our OO code compiled and tested on windows failed on unix because of a case problem. So much for strong typing.
Deployment problems - no. Being consistent - yes,
particularly on remembering where the camel casing
was.
Exactly. And I am glad to see Dr. Mercer-Hursh seems to be in the same camp:
"com.cintegrity"
Actually the other way around. The other day we had the problem that our OO code compiled and tested on windows failed on unix because of a case problem. So much for strong typing.
Isn't this really just a deficiency of Windows? I.e., if you are consistent in your naming in the code, it will run either place, but Windows will allow you to be inconsistent to some degree.
Sounds like a possible job for ProLint.
In my naming, I have been using com.cintegrity in lower case because it seems to me that is the way I see it done. I.e., as a domain specification it does not have case and thus is represented all lower case. But, everything below that, within the domain, is camel case. I am reconsidering this at this point as to whether I should join the crowd and go with the .NET style, simply because there is no actual value in the com. portion of this name. If so, then my topmost package would become CIntegrity.
Sounds like a possible job for ProLint.
No need. Our lowercase convention solves this forever.
If so, then my topmost package would become CIntegrity.
Looks like you are not deploying on *nix, or you would be heading for a daunting task.
Actually the other way around. The other day we had
the problem that our OO code compiled and tested on
windows failed on unix because of a case problem. So
much for strong typing.
There is no actual deployment problem with
mixed
case file names unless you do something stupid
like
name two files in the same location the same name
in
different case and then try to deploy on an OS
that
can't tell the difference. Other than that, is is
just having to be consistent.
Actually the other way around. The other day we had
the problem that our OO code compiled and tested on
windows failed on unix because of a case problem. So
much for strong typing.
Progress have always recommended that you use lower case for anything that ends up on disk, because *nix is case sensitive and Windows is not.
Your example illustrates one of the reasons, the problem might actually be worse the other way around as you could create many files on *nix where the only difference is the casing, thus making it impossible to deploy on Windows.
But in spite of this I have serious problem recommending the use of lower case naming for classes in OO. I agree with Thomas that these issues are controllable and when they do occur they are easy to identify and fix (as in your described case).
I realize that a single deployment failure can be disastrous, so I cannot go all the way and recommend camel casing, but I am convinced that abandoning camel casing have a huge cost on your day to day development and have a negative long term effect of your code (classes and libraries).
The camel bumps create a pattern that makes it faster to identify, both because of the “visual bumps” and the fact that the upper cased characters identify the logical words.
I am convinced that increased readability and fast identification alone outweighs the potential risk that mixed casing adds to deployment.
But the most important benefit of camel casing is that it promotes longer and more descriptive names. This is important in any language, but OO typically also have far more objects, so good names are even more important.
Lower case may have made sense when file names could not be longer than 8 or 12 character, since you needed to shorten your names a lot. Camel casing is almost an invention that makes it possible to really take advantage of long names.
Would Java have been successful if they had used lower cased classes? I do not think so, so even if I'm not yet brave enough to recommend camel casing, I most certainly will never again recommend lower casing.
Our lowercase convention solves this forever.
At the expense of readability.
And, essentially the only place I deploy, short of tests and a few specialized projects is on *nix.
Would Java have been successful if they had used lower cased classes?
I was referring to the fact that Java are using camel casing and can be deployed on both Windows an *nix (and that it is quite successful in this).
I am assuming that ABL is very similar and if this makes sense in Java then it does for us too, but there is a also a big difference in that Java is case sensitive and ABL is not.
I'm not able to see if what this actually means, but I may very well overlook something here. Maybe someone can clarify?
Are there any feature in Java (case sensitive? other?) that makes it easier to write and deploy camel cased classes in Java than in ABL?
are there any feature in Java (case sensitive? other?)
that makes it easier to write and deploy camel cased
classes in Java than in ABL?
My guess is that Java would not allow the compilation of incorrectly cased code whereas ABL does (on windoze).
Might the reason be that ABL relies on the underlying operating system for files and Java does not/not entirely?
Message was edited by:
Peter van Dam
My guess is that Java would not allow the compilation of incorrectly cased code whereas ABL does (on windoze).
This is certainly true and also a rather important difference. A case sensitive language probably eliminates the problem when developing in Windows and deploying on *nix.
My guess is that Java would not allow the
compilation of incorrectly cased code whereas ABL
does (on windoze).
This is certainly true and also a rather important
difference. A case sensitive language probably
eliminates the problem when developing in Windows and
deploying on *nix.
How about a new startup parameter that forces class references to be case sensitive? Such an option would certainly convince me to use camelcase.
Progress have always recommended that you use lower case for anything that ends up on disk
Of course, this was a recommendation which originated in the mid-80s when it was also recommended to keep all file names to 8+3 ... not doing that any more, are we?
Not to mention that I can't say that I look to PSC as the arbiter of style!
Which said, your reasons for why not anymore resonate with mine.
How about a new startup parameter that forces class
references to be case sensitive? Such an option would
certainly convince me to use camelcase.
You'd have my vote on the ERS!
How about a new startup parameter that forces class
references to be case sensitive? Such an option would
certainly convince me to use camelcase.
Good suggestion that would also make me able to fully recommend camel casing for OO...
You'd have my vote on the ERS!
The ERS is the right way to go.
I also think this can be resolved by tooling (Eclipse, Prolint). The benefit of tooling is that you can add far more "restriction" options. (see Eclipse for Java)
Of course, this was a recommendation which originated
in the mid-80s when it was also recommended to keep
all file names to 8+3 ... not doing that any more,
are we?
There is really no point in camel casing with a strict size limit and long names require camel casing.
Not to mention that I can't say that I look to PSC as
the arbiter of style!
This recommendation is purely based on the mentioned deployment issues and not on style. This only really became a style issue with the introduction of OOABL.
Let me reemphasize that I would only consider using camel casing for classes. It is less beneficial with the more verbose run statement. This view may be affected by the fact that I’m used to shorter names with procedures, but I also think the nature of OO makes it more natural and important to use longer and clear names (as well as sweeter to use short nice ones).
Your general point is still an important one. The world and the ABL is constantly evolving and old styles and conventions become outdated. I think both upper casing and hungarian notation are examples of styles that has become more and more obsolete and that has become directly counter productive, particularly in OOABL (with maybe a very few exceptions, like a hungarian prefix for private members).
I also think this can be resolved by tooling
(Eclipse, Prolint). The benefit of tooling is that
you can add far more "restriction" options. (see
Eclipse for Java)
I'd also wish much more other options on a Progress resource like:
- Compile into lower cases.
- Compile into GUI and TTY in different directories (for some files or folders)
- Do not compile at all
It is less beneficial with the more verbose run statement.
It is something I have been doing for years with IPs in SPs to give them meaningful names. That is not a case-sensitive context, of course, so it is safe, but the reasons for using the CamelCasing are the same.
I guess we will just have to disagree about some flavor of Hungarian. Are you advocating variable names like CharacterVersionOfThatDollarAmount ?
It is less beneficial with the more verbose run
statement.
It is something I have been doing for years with IPs
in SPs to give them meaningful names. That is not a
case-sensitive context, of course, so it is safe, but
the reasons for using the CamelCasing are the same.
Sorry, my bad. The original discussion was about physical elements that need to be deployed, so I was only referring to the procedure name and "forgot" that you run IPs.
I fully agree on IPs also having camel casing.
I guess we will just have to disagree about some
flavor of Hungarian. Are you advocating variable
names like CharacterVersionOfThatDollarAmount ?
DollarAmountString maybe... I have to admit that this is an ideal. I still commonly use hungarian data type identifiers in non-OOABL, but it does not look good and the only benefit the prefixing provides is that it is faster to make new names. I'm not sure that was the original intent.
The problem with hungarian notation is that one have to change from "word" reading to "bit" reading to actually decipher the prefix code. The information is often easier to get from the context. It's a matter of too much information upfront at the cost of the overall information. It might have made sense in include files or even old style large flat procedures, where you do not know where the definition is or where it is really far away, but modern tools makes this info available at need and modern code like OOABL also tends to have smaller methods and better separation of concerns all of which contributes to making the hungarian notation redundant and noisy.
Well, as I said, we will just have to agree to disagree. And, I would not like all versions, by any means, but I do like my version. If one gets into a long string of prefix information, like the a_crszkvc30LastNameCol example in my article, then clearly it is absurd and gets in the way, but lchDollarAmount for a local scope character version of the dollar amount is something that I find easy to read and informative when I need to pay attention to it.
Well, as I said, we will just have to agree to
disagree. And, I would not like all versions, by any
means, but I do like my version. If one gets into a
long string of prefix information, like the
a_crszkvc30LastNameCol example in my article, then
clearly it is absurd and gets in the way, but
lchDollarAmount for a local scope character version
of the dollar amount is something that I find easy to
read and informative when I need to pay attention to
it.
I find it hard to argue against hungarian notation for some scoping also in OOABL. I think it is important to differentiate members and possibly also input parameters. (Java/Eclipse differentiates members with color coding). But this does mean that I do not need to use the "l" prefix to identify local variables, since every variable that does not have a prefix then is local.
I assume you agree that hungarian notation never should be used in properties or methods? At least not public ones. Other than that I can agree to disagree...
I tend to prefer a system in which null means null, i.e., does not apply, rather than null mean local. I.e., there is a fourth character in my system which indicates directonality for parameters, but that doesn't apply to anything that is not a parameter and so most prefixes are three letters. (directionality + scope + two letters for type).
Properties I have been thinking of like database columns, which get only a two letter prefix for type.
Methods, IPs, etc., no prefixes.
I tend to prefer a system in which null means null,
i.e., does not apply, rather than null mean local.
I'm not sure I got this, but my point about NOT having a prefix for local variables is based on the fact that the vast majority of variables are local, so I would only mess up the name for the few exception cases.
The names are for humans primarily and omitting information is actually one of the more efficient ways to provide information. Humans are good at detecting patterns and differences.... meaning and context. Hungarian notation seems more suited for mechanical robots...
I.e., there is a fourth character in my system which
indicates directonality for parameters, but that
doesn't apply to anything that is not a parameter
and so most prefixes are three letters.
(directionality + scope + two letters for type).
Properties I have been thinking of like database
columns, which get only a two letter prefix for
type.
It kind of makes sense to have the same standard for properties and database columns, although I strongly prefer camel casing in database naming due to loss of proper name sort in lists and tools. (In some cases one are actually better off with lower casing because of the name being used in dump files and such)
But this only makes sense for objects that represent persistent (physical) data.
I think it would be a huge mistake to use hungarian notation for component properties. Components have far more object properties than primitive ones. This is particularly true with visual objects. I guess one tend to have far fewer properties in non-visual components, but I still think most OO components that do not represent persistent data will have most object properties. Following a hungarian convention then all properties in a visual component will have the same prefix in front.
Note that I think it would be wrong to do this with primitive properties too. Look at Infragistics or any other .NET toolkit. (Ok, I have not seem them all, but I think you have to look long to find anyone that uses hungarian notification on properties)
Message was edited by:
Havard Danielsen
I'm not sure I got this, but my point about NOT having a prefix for local variables is based on the fact that the vast majority of variables are local, so I would only mess up the name for the few exception cases.
I was responding specifically to the l in lch. I'm going to have the ch prefix regardless, especially on variables defined at the level of the class since the class can be fairly large. I'd much rather be uniform and consistent than save a character or two or introduce possible confusion. E.g., If I have tblCustomer.chName or a class Customer with property chName I don't also want to have a method scoped variable called chName, I want it to mchName.
Humans are good at detecting patterns and differences.... meaning and context. Hungarian notation seems more suited for mechanical robots...
Frankly, at times robots write better code. If one has a variable TotalAmount, the robot with its parser can tell where it is defined and what its type is ... but the human has to look around to find that. But, by labeling it mdeTotalAmount, the human immediately knows that it is a decimal quantity local to the current method or ipdeTotalAmount that it is an input parameter to the method.
It kind of makes sense to have the same standard for properties and database columns, although I strongly prefer camel casing in database naming due to loss of proper name sort in lists and tools. (In some cases one are actually better off with lower casing because of the name being used in dump files and such)
Camel casing for table and field names to be sure. Dump names is a minor, one-time setup issue. Don't know what you mean about the sorting unless you are thinking of the issues that arise with dashes and underscores in those names.
Following a hungarian convention then all properties in a visual component will have the same prefix in front.
You lost me somewhere. They have a prefix according to type. The component itself has no prefix.
I think you have to look long to find anyone that uses hungarian notification on properties
I am used to being in the minority about my preference for a form of Hungarian Notation. Doesn't keep me from feeling that I am right, otherwise I would have given in on upper case keywords 25 years ago.
How about a new startup parameter that forces class
references to be case sensitive? Such an option would
certainly convince me to use camelcase.
You'd have my vote on the ERS!
Start voting! ERS# 0000003887
Hi Peter, your request is still not available in the ERS...
Hi Mike,
(How can I quote here?)
It took me a few days to get back into the new PSDN and find this forum back.
Then I had to find out why my request is not visible in the ERS. When I look at it the status is NEW which means:
"The request is newly entered. Product management has been notified with the request information. The request will be looked at and will be tagged with the glasses icon to indicate that it was correctly categorized."
So I guess we have to wait for Product Management now...
BTW Of course we still have the problem in our app at the moment and in researching a related issue I stumbled upon PKB entry P129437 that states that my request is already implemented as of 10.1C...
rbf schrieb:
Hi Mike,
(How can I quote here?)
Hi Peter, in the top row of the editor buttons the rightmost button (Quote previous message).
I believe voting is open now!
Indeed.
Just a note: CamelCase (1st letter in caps) - if you are referring to the "UpperCamelCase", it is now mostly referred to as PascalCase. CamelCase is now designated for the form where the first letter is in lower case, originally termed as LowerCamelCase.
We might as well use 'PascalCase' and 'CamelCase'
Since ABL doesn't support underscore as the beginning letter of a variable, I suggest falling back to 'm_' for class level declaration (yes, don't put too much thinking about how the .NET designer widget naming break Microsoft's own standard).
I'm not so sure why you will need to prefix variable with a type indicator.
I'm not so sure why you will need to prefix variable with a type indicator.
I haven't updated this to my current standards, but here is one statement http://www.oehive.org/Hungarian
I have dropped the underscore in the last couple of years and need to expand the table for new types, but the concept is set out there.
As the Architect's intellisense matures the need for prefixed variable is even less necessary. If you happen to have tons of variables in a certain scope, I'm not exactly sure if the code is still OO.
Why do you think intellisense does anything for the readability of code?
While the use of OO changes the nature of scope, there are always three important scopes in a class - class wide, limited to a method, and a parameter. To me, knowing whether a variable, buffer, or whatever is local or not, is a very important piece of information.
Doesn't the intellisense already tell you all that? I think only prefix(or form) that tells where the variable is scoped is sufficient. As for input parameters, that is just a locally scoped variable. Output parameters use should be minimized and elevate the use of functions. Use a class definition for the return value if the method needs to set and return several values.
jquerijero schrieb:
Doesn't the intellisense already tell you all that?
Intellisense may support you in the moment that you type code - but not 5 minutes or 5 month or 5 years later when you have to read code. No matter if it's your own code or code somebody else produced.
Intellisense is only going to tell you about what you are pointing at. When I want to read code for understanding, I don't want to have to slow myself down by pointing to everything to figure what it really is.
Fascinating, so the name of the variable is not enough. "To be procedural or not to be . . ."
The name of the variable *is* enough .... when it has a prefix.
Not only that, it works in printed listings as well!