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? 
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 ]/)_ ~ [ Kent Dahl - Kent Dahl ]/~
))_student_/(( _d L b_/ (pre-) Master of Science in Technology )
( __õ|õ// ) )Industrial economics and technological management(
_/ö____/ (_engineering.discipline=Computer::Technology)