Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

(OT) Editor-neutral code formatting

by Ovid (Cardinal)
on Feb 07, 2002 at 01:01 UTC ( #143767=perlmeditation: print w/replies, xml ) Need Help??

Recently, I've had some discussions with grep regarding coding standards. Some of the standards have been fairly straight-forward. Code must use strict, run clean under warnings (unless special permission is sought under exceptional cases), encapsulated functions, etc. Those are pretty standard, but grep noticed that my coding style has changed a little bit and he asked me about it. Since I've been evaluating several different editors such as Homesite, Textpad, vim, etc, I have adopted an "editor-neutral" coding style. grep was considering making this a standard, but so many programmers consider this a near-religious issue that I am concerned that we won't see enough benefit compared to programmer gripes.

Here are the basic points of the style that I am using:

1. Indent data structures and arguments to subs rather than leaving them hanging off to the right:

sub ugly_formatting { my %conn_data = @_; my $dbh = DBI->connect( $conn_data{ data_source }, $conn_data{ use +r }, $conn_data{ pass }, { RaiseError => 1, AutoCommit => 0, LongReadLen => 65_634 } ) or die DBI->er +rstr; $dbh; }

Instead, I do this:

sub _connect { my %conn_data = @_; my $dbh = DBI->connect( $conn_data{ data_source }, $conn_data{ user }, $conn_data{ pass }, { RaiseError => 1, AutoCommit => 0, LongReadLen => 65_634 } ) or die DBI->errstr; $dbh; }

2. Curly braces should be aligned vertically over themselves on the same scope, rather than trailing off the end of a line. Quick, where's the missing brace:

if ( exists $database->{ $table }{ _unique } ) { my @unique_fields = @{ $database->{ $table }{ _unique } }; foreach my $field ( @unique_fields ) { my %field_count; my $sql = "SELECT $field FROM $table"; my $fields = $dbh->selectall_arrayref( $sql ); foreach ( @$fields ) $field_count{ $_->[0] }++; } foreach ( keys %field_count ) { if ( $field_count{$_} > 1 ) { print $err "Table: '$table' Unique field: '$_' was fou +nd $field_count{$_} times\n"; $error_count++; } } } # next $field }

If you vertically align corresponding braces:

if ( exists $database->{ $table }{ _unique } ) { my @unique_fields = @{ $database->{ $table }{ _unique } }; foreach my $field ( @unique_fields ) { my %field_count; my $sql = "SELECT $field FROM $table"; my $fields = $dbh->selectall_arrayref( $sql ); foreach ( @$fields ) $field_count{ $_->[0] }++; } foreach ( keys %field_count ) { if ( $field_count{$_} > 1 ) { print $err "Table: '$table' Unique field: '$_' was fou +nd $field_count{$_} times\n"; $error_count++; } } } # next $field }

To me, the problem just leaps out at me. As I sometimes wind up with really complex structures, vertical alignment of the braces seems to help.

3. Indentation can start with tabs for leading whitespace, but embedded whitespace must be spaces.

That might sound a bit weird, but many editors have tabs at different settings. Maybe they're 8 spaces. Maybe they are 4 or 2 (I've heard rumors of them viewing as 6 spaces, what heresy!). By ensuring that only leading whitespace (/^\s+/) is tabs (spaces are okay, too), but all embedded whitespace is comprised of spaces, you ensure that code won't wind up with a bizarre visual appearance, depending on the editor. For example, I recently encountered the following code (tabs are changed to spaces so you can see what I mean):

my %page_control = ( Add => { EmploymentListing => { page => 'e +m-main-add-employment.tmpl', function => \&add_emp +loyment } }, Edit => { EmploymentListing => { page => 'e +m-main-update-del-employment.tmpl', function => \&update +_delete_employment } }, Delete => { EmploymentListing => { page => 'e +m-main-update-del-employment.tmpl', function => \&update +_delete_employment }

Now, that's pretty ugly, but that's with tabs rending four spaces in width. I opened this up to work on it in an editor that renders tabs as being eight spaces wide:

my %page_control = ( Add => { EmploymentListing => { page => 'e +m-main-add-employment.tmpl', + function => \&add_employment } }, Edit => { EmploymentListing + => { page => 'em-main-update-del-employment.tmpl', + function => \&update_delete_employment } }, Delete => { EmploymentListing + => { page => 'em-main-update-del-employment.tmpl',

That's an even worse mess. I took some time to convert it:

my %page_control = ( Add => { EmploymentListing => { page => 'em-main-add-employment.tmpl', function => \&add_employment } }, Edit => { EmploymentListing => { page => 'em-main-update-del-employment.tmpl', function => \&update_delete_employment } }, Delete => { EmploymentListing => { page => 'em-main-update-del-employment.tmpl', function => \&update_delete_employment } } };

Note that rule 3 doesn't do that much good if rule 1 is ignored.

Now, here's the sad truth: I don't like this. Somehow, it grates against my sense of aesthetics. So why am I doing it? Because I think that in the long run, code is much cleaner and easier to read, regardless of the editor one chooses. Further, I feel that scoping issues will be easier to track down like this.

Here's the rub: is enshrining this into standards the way to go? I think many programmers would rebel. I really don't think we'll get much benefit. grep wants the standards, though, to ensure that we don't wind up with a bunch of different programmers reformatting everyone else's code every time they work on it (yes, I'm guilty of that :). Any thoughts?

Cheers,
Ovid

Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Replies are listed 'Best First'.
Re: (OT) Editor-neutral code formatting
by kschwab (Vicar) on Feb 07, 2002 at 04:01 UTC
    This doesn't really address the meat of the topic, but perltidy saves me tons of time with reformatting code.

    It's also handy at pinpointing nesting errors.

    Lastly, it supports several types of bracing, and can translate back and forth. This way you can support one type of production code, but everyone can code how they want to.

    ( --opening-brace-on-new-line, --brace-left-and-indent,--opening-brace-always-on-right, etc)

Re: (OT) Editor-neutral code formatting
by lachoy (Parson) on Feb 07, 2002 at 05:52 UTC

    All MO, 2c, grain of salt, etc.:

    - The scoping issues you mention here could be solved with any editor worth its salt. Relying on indenting to solve it for you is a bad idea because...

    - Indenting styles can change. Personally, I hate this indenting style. Anything that wastes this much vertical space makes me cringe. And tabs are such a PITA that I never use them. (ObHref to JWZ's writeup on this.)

    That said: keeping code readable by everyone who uses it on a daily basis is extremely important. When I code in Java at work I use a different style than I do Perl (and Java) at home. (But still no tabs :-) And for all the differences between the two different styles, it takes me at most 30 seconds to context switch, and that's when I haven't used one or the other for a few days.

    Also, I've found that getting all the coders talking about style issues rather than dictating what thou shalt do is generally more effective at getting people to stick to it. (Not saying you were doing that, just another reference point.)

    Chris
    M-x auto-bs-mode

Re: (OT) Editor-neutral code formatting
by clemburg (Curate) on Feb 07, 2002 at 10:44 UTC

    If you really need to think about indenting, your code is too convoluted. Break it into more functions that do less. Otherwise you don't need to think long about it, so it is not important.

    Case 1 you present is an example of a piece of code where indenting style really does not matter.

    Case 2 you present is not really hard, either, but if you feel that indentation really matters there, you should rewrite it breaking it into more functions.

    I often find myself playing around with several ways to indent a particular line of code (in Emacs, so "playing" is the right word), only to notice later that is has vanished because I had to introduce a function to hide the complexity from my bug-introducing typing fingers ...

    As for the other side of indenting conventions (ensuring a consistent layout for whatever reason) - only tools will help here, as long as people view an indenting style as part of their personality. (Hint: they should worry about more important things ... )

    Christian Lemburg
    Brainbench MVP for Perl
    http://www.brainbench.com

Re: (OT) Editor-neutral code formatting
by dorko (Prior) on Feb 07, 2002 at 03:51 UTC
    Ovid,

    ++ to you for saving my sanity. That's just about exactly the format I use to code. I don't think I've ever seen anyone format quite like I do.

    The only thing I do differently is to keep the braces in-line with the block that surrounds them (indenting them all) like so:

    
    sub_connect 
           {
           my %conn_data  = @_;
           my $dbh = DBI->connect(
                    $conn_data{ data_source }, 
                    $conn_data{ user }, 
                    $conn_data{ pass },
                            {
                            RaiseError  => 1,
                            AutoCommit  => 0,
                            LongReadLen => 65_634
                            } 
                    ) or die DBI->errstr;
            $dbh;
            }
    

    I like the way this quickly delineates function definitions and gives the reader a bird's eye view of the major chunks of code.

    Cheers!

    Brent

Re: (OT) Editor-neutral code formatting
by dreadpiratepeter (Priest) on Feb 07, 2002 at 14:38 UTC
    "Curly braces should be aligned vertically over themselves on the same scope, rather than trailing off the end of a line."
    Actually, as a disciple of the One True EditorTM, I have a very editor specific reason for prefering them at the end of the line. If I move onto a closing brace, the opening brace flashes. If the opening brace is not on the screen, emacs shows the line that the brace is on in the status area. "for (;;) {" is useful, "{" tells me nothing.
    Besides emacs indents for me, and will tell me if things are wrong by not indenting correctly. It's a wonderful feedback loop (along with color highlighting, try missing a quote and watching everything look like a string, easy to spot and fix).

    -pete
    Entropy is not what is used to be.
Re: (OT) Editor-neutral code formatting
by Masem (Monsignor) on Feb 07, 2002 at 14:52 UTC
    More as food for thought, given all the suggestions that we've had above, I know Damian was planning to rewrite Parse::RecDescent to handle complex code better, possibly having a Parse::Perl module that can parse and build a resulting tree structure for perl code. However, this latter project I believe was to be part of Perl 6 (I know I read it here on PM, but I cannot find the link). In any case, once we have a definitive parse tree for Perl, as opposed to relying on parenthesis matching, generating any structure for perl source will be rather simple.

    -----------------------------------------------------
    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
    "I can see my house from here!"
    It's not what you know, but knowing how to find it if you don't know that's important

Re: (OT) Editor-neutral code formatting
by FoxtrotUniform (Prior) on Feb 07, 2002 at 17:25 UTC

    Line length is a point that wasn't addressed. I try to keep my lines within about 70 characters when writing code, on the off-chance that someone with an 80-column editor and 8 spaces of code numbering (like, say, vi on the server console) ever has to read it. I can only wish that some of my colleagues, who like small fonts and large windows (and therefore have no problems with two- or three-hundred column lines) would feel the same way.

    As an aside, this sort of issue crops up even between programmers who use the same editor, but differently configured. At work, I use a rather heavily configured vim, a couple of other people use similarly (but subtly differently) customized vims, the sysadmin likes his nvi session to be as close to Joy's as it can get, etc. "Your code is unreadable in my editor!" "Use my editor instead, then!" just doesn't cut it.

    --
    :wq
Re: (OT) Editor-neutral code formatting
by ignatz (Vicar) on Feb 07, 2002 at 12:13 UTC
    Having a coding standard for a specific project is really useful.
Re: (OT) Editor-neutral code formatting
by t'mo (Pilgrim) on Feb 07, 2002 at 17:03 UTC

    (Since it's lunch time and I have a few minutes to venture even further OT...)

    I'm guessing, but you're also probably assuming that the font used in the editor is fixed-width. You may need to check that assumption, especially if you're going to try to "impose" any standard (on others or yourself). The editor in one IDE I commonly work with (IBM Visual Age Smalltalk) defaults to using a variable-width font (configurable, thank goodness), which can really make things look bizarre.

Re: (OT) Editor-neutral code formatting
by greywolf (Priest) on Feb 07, 2002 at 17:18 UTC
    We have had the problem of nasty looking indenting rear its ugly head on projects before. I like to use tabs for the main indenting and spaces for indenting structures like hashes etc. It seems to avoid nasty looking code.

    I don't think that forcing people to align/not align curly is a good idea braces since it really is just a personal preference. The important thing is to be consistant within a given piece of code/module. Anyone who can't figure out what's going on shouldn't be maintaining the code anyway.

    You have some good ideas here but I wouldn't go overboard enforcing standards that have no real impact on functionality or productivity.

    mr greywolf
Re: (OT) Editor-neutral code formatting
by jlongino (Parson) on Feb 09, 2002 at 17:31 UTC
    Fortunately, I am the only programmer in my area (sometimes application, sometimes sysadmin). Although I can do as I please, I try to make my code as readable and maintainable as possible. There has been only one project (in 13 years) that I've had to work with another programmer, and believe me, the visual appearance of the code was the least of my worries. If you have enough time to focus on this level of detail, you've obviously done an excellent job of training your programmers on the less aesthetic aspects of programming (maybe you could cut them a little slack :).

    I loathe the idea of including tab characters in code and so choose editors that allow me to specify the default tab spacing, indent size, and the option to convert all tab characters to spaces. This is probably due to the fact that I am partially brain damaged from prolonged exposure to Fortran.

    Curlies and code blocks? I generally prefer saving vertical space when using openning curlies, but am A.R. about keeping closing curlies on a line to themselves. I rarely forget an openning/closing curly and find that if I have trouble locating one, then I am probably neglecting modularization.

    Curlies and complex data structures? To me, this is an area where flexibility is a necessity. I try to keep a good balance between vertical/horizontal whitespace and readability. I definitely prefer version #3 of your %page_control, but would've done it a bit differently:

    my %page_control = ( Add => { EmploymentListing => { page => 'em-main-add-employment.tmpl', function => \&add_employment } }, Edit => { EmploymentListing => { page => 'em-main-update-del-employment.tmpl', function => \&update_delete_employment } }, Delete => { EmploymentListing => { page => 'em-main-update-del-employment.tmpl', function => \&update_delete_employment } } );

    --Jim

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://143767]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (4)
As of 2021-12-04 23:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    R or B?



    Results (30 votes). Check out past polls.

    Notices?