Nathaniel Talbott wrote:
> But that common ancestral namespace isn't arbitrary (and it certainly isn't
> just to save me typing): it's a logical separation of my code in to related
> parts. If, when I'm doing that separation, I deem that two classes should go
> in to the same module, it follows that those two pieces of code are closely
> related enough to (a) not worry about namespace clashes, and (b) to need to
> easily access one another's namespace. 

Fair enough, but what about all the constants of all the preceeding 
namespaces you opened? The rationale for polluting your namespace with 
these, is what I find arbitrary. A naive example:

module Text
   class Parser;end
   module SGML
     class Parser;end
     module HTML
       class Parser; end
     end
     module XML
       class Parzer; end # typo
       def self.parse_xml
         Parser.new # uh oh, this turns into an Text::SGML::Parser
       end
     end
   end
end

Now this typo is easily resolved, once you notice that the program 
doesn't do what you thought it did. (_If_ you notice it.) But why should 
one open the entire namespace of Text if you're just working on, say, 
the XML module? Do you really want to deal with all the (potential junk) 
that your co-workers fling into the Text namespace?

module Text::SGML::XML
   class Parzer; end # typo
   def self.parse_xml
     Parser.new # uh oh
   end
end

This will blow up with a nice NameError, in accordance with the "fail 
early" principle for catching bugs. So far so good.

> I'll admit that I still don't understand what benefit this new behavior
> adds, even if I _were_ to separate out my constants in to their own
> namespaces and include them. I see doing that as perhaps making this new
> behavior bearable, but I don't see any benefit in this new behavior when
> working like that.

Confession time: I probably wouldn't do that either. I'm too lazy. 
However, there is a middle ground. Back to the parser example.

Lets say you want to inherit the HTML and XML parser from the SGML 
parser, since entity resolving and a few other things are quite similar.

Now this won't work:

class Text::SGML::XML::Parser < Parser
end

But this will:

module Text::SGML
   class XML::Parser < Parser
   end
end

This might seem like a step backwards, as we have more than one body. 
However, notice that I "cut off" the namespace at Text::SGML, telling 
the reader that I am in need of it, and go on to implement all the 
methods of the XML parser that depends on the SGML stuff. I also avoid 
including the XML namespace, just in case there is something icky there.

In the next step, I'll implement some basic methods inside the parser 
that doesn't depend on SGML nor XML:

class Text::SGML::XML::Parser
   def boring_bookkeeping
   end
end

Here I cut of the namespaces completely, telling the reader:
"Just working on the parser innards, nothing to see here, move along!"

Then there will be methods that need other parts of the XML namespace, 
and I'll do something like:

module Text::SGML::XML
   class Parser
     def pure_xml_stuff
     end
   end
end

Now I seem to have been opening the Parser class umpteen times and for 
what? For separation of concerns. This could also have been done with 
mixins, I seem to recall this having been both discussed and advocated 
here earlier:

module Text
   module SGML
     module XML
       module SGMLSpecificStuffForXMLParser
       end
       module XMLSpecificStuffForXMLParser
         def pure_xml_stuff
         end
       end
       module UnspecificStuffForXMLParser
         def boring_bookkeeping
         end
       end
       class Parser
         include SGMLSpecificStuffForXMLParser
         include XMLSpecificStuffForXMLParser
         include UnspecificStuffForXMLParser
       end
     end
   end
end

But, AFAIK, you cannot do the namespace part of the separation of 
concerns with this approach. If the restrictions of the new M::C style 
is intended, the possibility to do this separation is one of the 
features it brings.


> Call it personal bias, but whenever an argument is made that a problem will
> only show up with a huge code base, I immediately question the validity of
> the so-called "problem". 

An admirable attitude. :-)

> The truth is, until someone writes that 10kLOC
> project, we don't know. And this is not an issue I've heard is a problem for
> any practicioners. As a matter of fact, as a practicioner working on a
> fairly large Ruby app, I have no trouble with namespace pollution, and I do
> get tired of typing "module x; class x; module x; module x; class x" ad
> nauseum. I was hoping this new nesting would save me that, but it doesn't
> look like it will. C'est la vi.

I cannot prove it, nor will I attempt, as matz' decisions will suffice 
for me. This is more of a "gut feeling" that comes from my (limited) 
experience that was semented securely after being bulldozed by a more 
knowledgeable ex-co-worker on the "fail early" issue. But that was in C++.

> But I enjoy programming in Ruby and detest C++; why would I want Ruby to
> emulate it? 

My point here was that the old way emulates C (only #includes), while 
the new style emulates C++. You may detest one or the other, but the 
namespace issue is one thing I like about C++ over C. Or am I the only 
one who gets prefix paranoia reading things like the Ruby source code? ;-P

> I guess, in summary, I _like_ descendent code having easy access
> to constants defined in its ancestors' namespace. I don't think it's a
> problem having this behavior (even in large projects),

In Ruby this might be true. Personally I'll feel safer applying some 
"lessons learned" from other languages pro-actively.

> Perhaps this is where we diverge - I'd prefer to make programming easier now
> (by perhaps having more than I need) rather than prematurely fix problems I
> think I _might_ have.

Yes, but there is more than premature fixes on my mind. Readability and 
expressiveness are my biggest reasons for using Ruby and IMHO this new 
feature adds to that.

-- 
(\[ Kent Dahl ]/)_    _~_    _____[ http://www.pvv.org/~kentda/ ]_____/~
  ))\_student_/((  \__d L b__/ (pre-) Master of Science in Technology  )
( \__\_?|?_/__/ ) _)Industrial economics and technological management(
  \____/_?_\____/ (____engineering.discipline_=_Computer::Technology___)