Wild ideas: Finding a missing 'end'

M

Mat Schaffer

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
 
N

N Okia

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.
 
D

dblack

Hi --

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.

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
http://www.manning.com/black => book, Ruby for Rails
http://www.rubycentral.org => Ruby Central, Inc.
 
M

Marc Heiler

unknown said:
Hi --



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. :)
 
D

Dr Nic

Using indentation is dangerous, because indentation doesn't mean
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
 
D

dblack

Hi --

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 :)


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
http://www.manning.com/black => book, Ruby for Rails
http://www.rubycentral.org => Ruby Central, Inc.
 
P

Paul Battley

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 this?

---

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top