On Fri, Apr 25, 2003 at 02:51:41AM +0900, Dave wrote: > I'm still a bit confused, though. I've read messages from matz here > saying that he is against declarations that are for the sole purpose > of helping the compiler figure out what's going on. And yet that is > effectively what must be done in this case -- some declaration like x > = nil. Well, I agree that it's a declaration in all but name :-) You still need some disambiguating rule as to whether "x" means a local variable or method self.x Ruby's way is surprising to people new to Ruby, but it's easy to get used to. The alternatives? - explicit declarations or - prefixing all local variables with some symbol, e.g. %x or - forcing all method calls to have an explicit receiver They would all make Ruby look more like Perl, and we wouldn't want that :-) The current behaviour works in most cases, and if you really do need to write a loop which reads a variable before it's been assigned, then a quick 'x = nil' above it sorts it out. In fact under the current scoping rules you need that outside a block iterator anyway, otherwise x is local to the block itself and gets a fresh instance for each iteration. > It seems that the compiler has no lookahead -- when it sees > "puts x if defined? x" it must decide then and there, based on what it > has seen until that point, if x is a variable or method. It doesn't > matter that even the very next line uses x as a variable. > > Is there a particular reason that such decisions can't be postponed > until the rest of the current scope region has been looked at? Ruby is a one-pass compiler. This does have some very useful benefits - for example you can pass in a program on stdin via a pipe, and it can compile cleanly without having to buffer up potentially the whole source. > The > semantics would make a lot more sense then, I think, even though it > might not take care of everything (like eval "puts x" for example, > before x is defined). Well it would still make sense - x would be a local variable containing 'nil' at that point. I'm not sure the rule would be much simpler to understand than the current behaviour though, or worth the complexity to implement. It would also mean that you couldn't test your script using irb: def x 99 end p x x = 4 Under your rules this should print 'nil', which requires looking into the future :-) It's effectively the same as the one-pass issue: your proposal would mean that you can't compile anything until the end of the current scope. Being able to compile and run a line at a time makes interactive programming much more feasible. Regards, Brian.