This does the same job without using eval:

class Module
  def lineage
    name.split(/::/)[0..-2].inject(self) do |mod, modname|
      mod.const_get(modname)
    end
  end
  def modspace
    lineage
  end
end

module X
  include Math
  module Y
    include Comparable
    module Z
      include Enumerable
    end
  end
end

x = X
y = X::Y
z = X::Y::Z

p x.modspace
p x.modspace.class

p y.modspace
p y.modspace.class

p z.modspace
p z.modspace.class

__END__
---------- Ruby ----------
X
Module
X
Module
X::Y
Module

Output completed (0 sec consumed) - Normal Termination

Not that I think eval is evil. I find it very handy.

I'm not sure what it means for X's modspace (aka 'lineage') to be X but that's
how the original worked. Perhaps it should be Module?
You can get this behaviour by changing inject(self) to inject(Module).

I'm curious - what would you do with this?

Regards

Sean