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.