From: Brian Candler Date: 2004-10-08T20:26:55+09:00 Subject: Re: quality of error messages On Fri, Oct 08, 2004 at 08:06:27AM +0900, Yukihiro Matsumoto wrote: > |> % ./script.rb > |> script.rb:6: warning: inconsistent indentation level. > |> script.rb:13: parse error > |> > |> This should make it easy to find such errors. > > |That seems like a nice idea to me. This would be nearly the same as the > |autoindenter so, only that it does not indent but spit out warnings. > > I'm afraid that it might cause tab-space indentation war like in the > Python community. The issue is much smaller though, since it is not > mandatory. I think that you don't have to enforce any particular indentation style or amount of space on each line - only that it is consistent between begin and end. If we define the 'nesting depth' as the number of module / class / def / do / if sections we are within (i.e. the number of matching 'end's we expect to see), then: - at the start of each line, count the number of spaces. Ignore lines which consist entirely of whitespace. R1: if the nesting depth is the same as the previous line, then raise a warning if the number of spaces is not the same as the previous line R2: if the nesting depth is greater than the previous line, then remember the indentation of this line associated with this nesting depth (e.g. on a stack) R3: if the nesting depth is less than the previous line, then raise a warning if the number of spaces is not the same as the last line with the same nesting depth # hello [] R1: check indentation == 0 class Foo [] R1: check indentation == 0 def m [2] R2: push 2 wibble [2,6] R2: push 2 bibble [2,6] R1: check indentation == 6 end [2] R3: check indentation == 2 def [2] R1: check indentation == 2 end [2] R1: check indentation == 2 end [] R3: check indentation == 0 Some details left out, but you get the idea. When comparing the number of spaces at the start of a line, I'd count tabs as moving to the next 8th column, as is usual in most cases, so that on one line matches 10 spaces on another line. If people don't like that rule, it still doesn't matter; they just need to be consistent in their use of either tabs or spaces. e.g. if you're using 4-space tabs then will not match but if you stick to one or the other, then they will match. It is common for me to take a bit of code and wrap it with 'module foo' / 'end' or 'if false' / 'end' without re-indenting the code inside. This system will still work for me: if false [] class Foo [0] i.e. nesting depth 1 has indentation 0 def m1 [0,2] end [0,2] end [0] end [] One other thing, you'd need to ignore subsequent lines of multi-line statements: a,b,c = 1,2,3 foo ( ... ) but I guess the parser must already have a mechanism which infers "the next line is a continuation of the previous" anyway. Regards, Brian.