Wild ideas: Finding a missing 'end'

I was just reading a nuby question from the rails list and I had this thought:

class MyClass
   def foo
     if true
   end
end

This code generates a parse error at the last line. Now most languages do this, so it's not a big deal. But how frickin cool would it be if a future version of ruby looked at the indenting and made a guess as to where the missing end/} might be.

Like:
test.rb:5: parse error, unexpected $, expecting kEND. Did you miss an "end" on line 4?

Maybe people have thought about this already. I'm just thinking out loud here, really.
-Mat

Yes, it has been considered. Unfortunately allowing the
interpreter/compiler figure this out only works in the extremely
simple case

Consider:

a=[1,2,3]
for i in a
begin
  if i > 1
    x = 3*i
  end
end
puts x

Obviously there is a missing end statement. However, where we put it
makes a big difference. If we put it before the puts x, we get a very
different output then if we put it after puts x. This is a simple
example as well, even more complex examples will show that it gets
very dangerous to let the interpreter figure out what you meant.

Using indentation is dangerous, because indentation doesn't mean
anything in ruby normally, and trying to figure out the right thing
would mean that we start having to be careful with indentation levels,
and code works in strange ways because we don't know ruby is 'helping'
us out. It can make for very hard to find bugs.

Like this?

···

On 29/07/06, Mat Schaffer <schapht@gmail.com> wrote:

This code generates a parse error at the last line. Now most
languages do this, so it's not a big deal. But how frickin cool
would it be if a future version of ruby looked at the indenting and
made a guess as to where the missing end/} might be.

---

def error_line(code)
  File.open('tmp.rb', 'w') do |io|
    io << code
  end
  s = `ruby -c tmp.rb 2>&1`
  if (s =~ /parse error/)
    return s[/\d+/].to_i
  else
    return false
  end
end

code = File.read(ARGV[0])

exit unless error_line(code)

lines = code.split(/\n/)

x = lines.length / 2
xmin = 0
xmax = lines.length

while l = error_line(code)
  if l < x
    xmax = x
  elsif l > x
    xmin = x
  else
    break
  end
  x = xmin + (xmax - xmin)/2
  code = (lines[0,x] + ['end'] + lines[x..-1]).join("\n")
end

puts("Error around line #{x+1}")

----

This is pretty rough code that I just threw together without much
thought, but it seems to work. Its temporary file handling leaves a
lot to be desired.

Paul.

Hi --

···

On Sat, 29 Jul 2006, N Okia wrote:

Yes, it has been considered. Unfortunately allowing the
interpreter/compiler figure this out only works in the extremely
simple case

Consider:

a=[1,2,3]
for i in a
begin
if i > 1
  x = 3*i
end
puts x

Obviously there is a missing end statement. However, where we put it
makes a big difference. If we put it before the puts x, we get a very
different output then if we put it after puts x. This is a simple
example as well, even more complex examples will show that it gets
very dangerous to let the interpreter figure out what you meant.

Using indentation is dangerous, because indentation doesn't mean
anything in ruby normally, and trying to figure out the right thing
would mean that we start having to be careful with indentation levels,
and code works in strange ways because we don't know ruby is 'helping'
us out. It can make for very hard to find bugs.

But surely just a warning can't be harmful, even if it mentions what
turns out to be the wrong line -- ?

David

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
   ----> SEE SPECIAL DEAL FOR RUBY/RAILS USERS GROUPS! <-----
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
Ruby for Rails => book, Ruby for Rails
http://www.rubycentral.org => Ruby Central, Inc.

unknown wrote:

Hi --

  x = 3*i
Using indentation is dangerous, because indentation doesn't mean
anything in ruby normally, and trying to figure out the right thing
would mean that we start having to be careful with indentation levels,
and code works in strange ways because we don't know ruby is 'helping'
us out. It can make for very hard to find bugs.

But surely just a warning can't be harmful, even if it mentions what
turns out to be the wrong line -- ?

David

I agree as far as giving the coder the exact error line in a better way
than currently, yes. That would help more than scanning the code for the
missing end. :slight_smile:

···

On Sat, 29 Jul 2006, N Okia wrote:

--
Posted via http://www.ruby-forum.com/\.

Using indentation is dangerous, because indentation doesn't mean
anything in ruby normally, and trying to figure out the right thing
would mean that we start having to be careful with indentation levels,
and code works in strange ways because we don't know ruby is 'helping'
us out. It can make for very hard to find bugs.

I think its better for it to guess than to just return the last line of
the file each time. Perhaps return multiple guesses.

Cheers
Nic

···

--
Posted via http://www.ruby-forum.com/\.

The problem with using indentation to even guess at an area in pretty much
any language other than python is that it would require a huge amount of
logic to account for the myriad possible edge cases.

What happens when a user mixes tabs and spaces?
If one line is indented 3 spaces and the next is 4 is that a typo or is it
an intentional indication of a subsection?
What happens when there's a long method call that the developer has decided
to indent a portion of on a second line instead of having the thing stretch
way off to the right of the typical viewing area?

You could go on and on and on and on with screwed up cases like this? Either
you write something complex enough to figure out what the hell us crazy
humans meant or you get misleading results which in my opinion is worse than
no results.

Remember, a solution in the Ruby core has to work for all users not just the
users who happen to have good and consistent indentation habits.

- kate = masukomi

Hi --

···

On Sun, 30 Jul 2006, kate rhodes wrote:

The problem with using indentation to even guess at an area in pretty much
any language other than python is that it would require a huge amount of
logic to account for the myriad possible edge cases.

What happens when a user mixes tabs and spaces?
If one line is indented 3 spaces and the next is 4 is that a typo or is it
an intentional indication of a subsection?
What happens when there's a long method call that the developer has decided
to indent a portion of on a second line instead of having the thing stretch
way off to the right of the typical viewing area?

You could go on and on and on and on with screwed up cases like this? Either
you write something complex enough to figure out what the hell us crazy
humans meant or you get misleading results which in my opinion is worse than
no results.

Remember, a solution in the Ruby core has to work for all users not just the
users who happen to have good and consistent indentation habits.

The solution could be to give a specific hint if it's a simple case,
and not if it isn't :slight_smile:

David

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
   ----> SEE SPECIAL DEAL FOR RUBY/RAILS USERS GROUPS! <-----
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
Ruby for Rails => book, Ruby for Rails
http://www.rubycentral.org => Ruby Central, Inc.