Apologies if this topic has already been beaten to death.
Oh, and for the long-windedness.
Using modules for namespaces is somewhat unwieldy. I'd call it one
of the few evil parts of Ruby, although its implementation is
understandable when viewed from an OO standpoint. It's just
tiresome to A) invent and B) use unique namespaces in Ruby (and
by 'unique' I mean FooSoft Inc. wrapping all their libraries inside a
module FooSoft).
Of the current commercial languages, the package system of Java is
likely to be the best for flexibility and uniqueness, although it
does suffer from verbosity--and I wouldn't mind seeing Haskell-style
limited export capabilities, either. This, of course, should be
possible to do in Ruby 'on top' of the current system.
But why use unique namespaces? Modules are certainly useful for
partitioning a project into its constituent parts, but unique
namespaces are only useful in the context of that code being used
by another party where it can prevent namespace clashes. This, of
course, is highly site-dependent: it may not be necessary at all,
they may already have a package with the same 'unique' namespace,
they may not like the module name, etc. etc.
Why not have the 'client' decide if and which namespace to assign
to a foreign library? As in, if I want to use FooBar Inc.'s Math
package, they need not wrap it in module FooBar, but can just ship
it as Math. Then I just wrap it to Extern, my namespace for all
third-party modules. In current Ruby, I suppose this can be achieved
with something like (please correct if I'm wrong, this is off the top
of my head):
···
-----
# Toplevel
# This is just an aesthetically pleasing (?) implementation,
# I'm not sure about using String for the ascribed purpose.
def import file
file[:module].module_eval(IO.readlines(file[:name]).join)
end
class String
def as module
{:name => self, :module => module}
end
# Convenience
alias :in :as
alias :into :as
end
# Usage
import "foomath.rb".as Extern
rand = Extern::Math.random()
-----
Or is that just counterintuitive? It would at least conceptually
free the module construct from doing double duty as the namespace
construct.
The Ruby implementation is obviously somewhat slow but it could be
written to use the same routines as require()/load() with the
exception of doing the loading in the context of a given module. I
think the above 'implementation' also handles altogether non-moduled
files but I may be wrong in my it's-Sunday-morning-and-I'm-at-work
stupor.
E