From: Stefano Crocco Date: 2008-03-15T16:41:44+09:00 Subject: Re: how to abruptly end a program? On Saturday 15 March 2008, Tom Cloyd wrote: > Joel VanderWerf wrote: > > Tom Cloyd wrote: > >> Joel VanderWerf wrote: > >>> Tom Cloyd wrote: > >>>> I read in (p. 303) - ""If Ruby comes > >>>> across a line anywhere in the source containing just “_ _END_ _”, > >>>> with no leading or trailing whitespace, it treats that line as the > >>>> end of the program—any subsequent lines will not be treated as > >>>> program code." > >>>> > >>>> That's not what's happening for me. The following - > >>>> _ _END_ _ > >>>> __END__ > >>>> _END_ > >>>> > >>>> all produce the same result for me - "undefined local variable or > >>>> method" > >>>> That DOES bring the program to an abrupt end, but its rather > >>>> ungraceful. Is this the intended result - a crash due to an > >>>> interpreter error? > >>> > >>> What the quote (a bit ambiguous perhaps) means is that the __END__ > >>> line and following lines are not treated as part of the program > >>> text. It has nothing to do with control flow. It's like comment > >>> block that runs to the end of the file without any explicit > >>> termination. (It's more than that because you can read it with DATA.) > >> > >> OK, but couldn't ANY uninitialized variable achieve the same messy > >> result? What's the point? This surely can't be the intended result. > >> Makes no sense to me. > > > > __END__ by itself on a line shouldn't exit the program. If you're > > getting that error, maybe there is an extra char on the line. A space > > perhaps? > > Yes, that would explain it, but I made sure this problem didn't occur > from the beginning, which is one reason I'm puzzled. I really don't see > anything wrong with what I'm feeding the interpreter. > > So, I did a different test program - > > require 'readline' > puts "test under way\ninput var: " > #opt = readline( "=--> \n") > opt = gets.chomp > puts( opt) > __END__ > puts( opt) > > result: > test under way > input var: > 5 > 5 > > Here, we don't get an error. We just get ignored. > This is nuts. > > t. As others said, when ruby sees the __END__ identifier on a line by itself (without leading or trailing spaces), it treats it, and any text following it, approximately as a comment. This means that the code is not parsed (syntax errors after that line aren't recognized) and, obviously, not executed. Besides, the constant DATA is set to a File object which contains that text. This is consistent with the result you get from your piece of code: without the __END__, 5 would have been written 3 times: the first when you entered it from the keyboard, the other two because of the two puts. Since the second puts is after __END__, instead, you only get it twice: the second puts is ignored. Try this, for example: puts "This is the class of DATA: #{DATA.class}" puts "These are the contents of DATA:\n\n#{DATA.read}" __END__ This is not valid ruby code The output is: This is the class of DATA: File These are the contents of DATA: This is not valid ruby code Of course, removing the __END__ line causes a syntax error: ./prova.rb:6: syntax error, unexpected kNOT, expecting $end This is not valid ruby code Regarding your first piece of code (the one which produces the NoMethodError), are you sure the error isn't produced before end? Stefano