Hi -- On Sun, 8 May 2005, Cyent wrote: > Nil arises in several places that I can think of. > > The most obvious case, and the case I think most people are concerned > about, is when referencing an uninitialized variable. That pertains only to instance and global variables, and I don't remember seeing a lot about it (though I haven't tallied the responses). > This case is flagged by -w, and hence I had mentally disregarded the > possibility when I wrote RCR 303. > > The next case is when nil is returned by something like a regex match or > an index out of bounds. That seemed to me to be what people were talking about mostly -- things like: /som(e n)on-matc(hing) regex/.match("blah").captures > The third case is when explicit set by the programmer, typically as a > default parameter to a method. > > The fourth case is to get around the lexical scoping umfeature of rubies > local variables. > > def foo > my_var = nil > box.each do |e| > my_var = e if e.blah > end > > use_var( my_var) > end > > This is another case of "nil means uninitialized". It's not that, exactly; rather, you're initializing a variable to nil. You've chosen nil to represent the initialized state of the variable, not an uninitialized state. Once you assign to it, it's initialized. > So what we have is a "nil" is a little too busy, means too much, is > overloaded too heavily. I'm not sure where the "too"s come from. How do you determine how much (or little) use should be made of such a construct? You can always initialize your variables to something else if you don't like using nil too much :-) > It means "uninitialized". > > It also means "no thing here" (as in return from regexp match (no > MatchData here), index out of bounds (no Array element here), and nil as a > default value.) It's not exactly "no Array element here"; it's more a default value. You can have nil as an array element; therefore, it cannot mean that there's no element. As with hashes, of course, the retrieval of the default value does not initialize the element: ruby -we 'a = []; a[3]; p a.size' 0 > I perfectly agree that "uninitialized" should throw a > NoMethodError. That's not what happens, though. If a local variable is uninitialized, you find out before you get to the point of sending it a message: bash-2.04$ ruby -e 'a.b' -e:1: undefined local variable or method `a' for main:Object (NameError) whereas NoMethodError happens when you send a message to an object. > Indeed I doubt if it should respond to some of the > methods it does respond to currently. I even think -w is too friendly, I > would prefer it to throw than to just warn. > > What I as thinking of by RCR 303 is nil as "no thing here" should respond > to all methods, do nothing and return "no thing here". > > So perhaps I should retract RCR 303 and created a new one suggesting and > differentiation between "uninitialized" and "no thing here", and > effectively RCR-303 for "no thing here". > > I would welcome suggestions as to how to craft this new RCR. A few years ago there was a discussion of some kind of NACK mechanism -- meaning, something that an object could give as a reponse when it didn't recognize a message, instead of raising NoMethodError. My main goal was to avoid this: obj.meth if obj.respond_to?(:meth) a repetition I've always disliked, and at the same time to avoid having to do this: begin obj.meth rescue NoMethodError ... end The big problem with NACK, though, was that it was incompatible with method_missing: it offered a different way to handle the same situation. Anyway, I thought the concept might be of interest in connection with the problem you're working on, and perhaps you can engineer it successfully. David -- David A. Black dblack / wobblini.net