in reply to The classical TAB issue

For level of indentation: 8 is popular in C. Java style guidelines mostly follow K&R, but specify a level-4 indent. The reason is that Java identifiers tend to be very long, and that if you are strict about indenting braces, you end up with a lot of levels of indentation before you get to any real code (one level for the class block, one for your method, and another for a try, which any non-trivial code will need). Perl is closer to C than Java, so I usually use 8, but I wouldn't be surprised to see many experianced Perl programmers use 4.

How to deal with people who don't use the same tabstop as you do is a problem. You could set it to output spaces instead of a literal \t, but I don't like having to do 8x or 4x to remove a level of indentation (in vi) when I can use simple x instead. Further, I like the level of indentation to show up exactly the number of spaces I have my editor set to. At the same time, I must remember that otehr people also want it to look right with different tab settings. I must respect their settings if I expect them to respect mine.

This code shouldn't have a problem with anyones' settings:

sub foo { <TAB>my ($bar, $baz) = @_; <TAB>if($bar) { <TAB><TAB>return $baz; <TAB>} <TAB>return 0; }

If I have tabstop set to 8 and someone else has it set to 4, it will look right in both cases. However, this code might not:

sub foo { <TAB>my %hash = ( <TAB><TAB>bar<TAB>=> 1, <TAB><TAB>baz<TAB>=> 1, <TAB>); <TAB>return %hash; }

The tab embedded in the hash syntax could end up at very different places. In the specifc example above, it probably won't be an issue. It would be an issue where one of the hash keys was particularly longer than the other. Instead of this:

my %hash = ( foo => 1, longer_key => 1, );

Someone with a shorter tab stop might see this:

my %hash = ( foo => 1, longer_key => 1, );

The solution I've found is to tab at the beginning levels of indentation for the block, but to put spaces in internal indentation. For example:

<TAB>foo<SP><SP><SP><SP><SP><SP><SP><SP>=> 1, <TAB>longer_key<SP>=> 1,

(It doesn't line up above, but it should if you replace each <SP> with a real space).

There are still a few situations where this won't work, but I think it's as close to making everyone happy as we can get. Except for Abigail-II, who isn't happy about anything :)

----
: () { :|:& };:

Note: All code is untested, unless otherwise stated

Replies are listed 'Best First'.
Re: <blocThe classical <TAB> issue
by Abigail-II (Bishop) on Apr 06, 2004 at 15:38 UTC
    You could set it to output spaces instead of a literal \t, but I don't like having to do 8x or 4x to remove a level of indentation (in vi) when I can use simple x instead.
    Learn your vi. Assuming your cursor is on the code, and not on the indent, using the 'x' method to remove a tab takes you two key strokes: 0x, or ^X. But there's another way, that will work with spaces as well, doesn't require the cursor to be on the indentation, and which is sensitive to movement commands (so you can outdent regions): <<. And to indent: >>.
    sub foo { <TAB>my ($bar, $baz) = @_; <TAB>if($bar) { <TAB><TAB>return $baz; <TAB>} <TAB>return 0; }
    If I have tabstop set to 8 and someone else has it set to 4, it will look right in both cases.
    Sure, in this simple example it will. But suppose you have your tabstop set to 8, write the above code, check it in to source control, and someone with a tabstop set to 4 checks it out, and modifies it as follows:
    sub foo { <TAB>my ($bar, $baz) = @_; <TAB>if($bar) { <TAB><TAB>if (fuzzle ()) { <TAB><TAB><TAB># Expression taking 60 characters. <TAB><TAB>} <TAB><TAB>return $baz; <TAB>} <TAB>return 0; }
    Looks great, with an 8 character margin on the right to spare, so it fits in the pleasing "72 character" width, and certainly it fits in the default 80 character window.

    The code is checked in, and you check it out again. You look at the code in your 80 character window, and the last four characters of the new code will appear wrapped to the next line. Yuck!

    If even becomes much yuckier if the coding guideline says "4 character indent", and some people use an 8 character tab-stop, and some use a 4 character tab-stop. Say the current block has <TAB> as indentation and two if/else statements are added, by different programmers. One will use <TAB><TAB> as indentation - the other <TAB><SP><SP><SP><SP>. Fun! Fun! Fun!

    Abigail

      Assuming your cursor is on the code, and not on the indent, using the 'x' method to remove a tab takes you two key strokes: 0x, or ^X.

      Hrm? A simple x has always worked for me, but then I also use vim with its nearly-modeless settings whenever I can get away with it. (I probably should have specified this above). Admittedly, removing any sizeable block of indentation can be done faster with a search-and-replace on those lines anyway.

      Sure, in this simple example it will.

      And that's exactly what I was trying to show: a simple example where any sane value of tab settings will work. There are probably more cases where they won't work than everyone on this site could list.

      ----
      : () { :|:& };:

      Note: All code is untested, unless otherwise stated

        Hrm? A simple x has always worked for me
        In any vi I've encountered the past 20 years, 'x' deletes the character under the cursor. So, if your cursor is on code, you first need to move the cursor to the indent. Hence '0x' to move the cursor to the first column, and delete that character, or '^X', which moves the cursor to the first non-white space character on the line, and then deletes the character before it.

        Abigail