2007/8/21, David A. Black <dblack / rubypal.com>:
> Hi --
>
> On Tue, 21 Aug 2007, Tim Pease wrote:
> > "A::B::C::D".to_class
> >
> > It could just be a wrapper for the core method rb_path2class -- which
> > does the same thing in Ruby C API land.
>
> It's a more general-purpose thing, though; it's for any constant, not
> just classes. It's really just a variation on const_get, which already
> will give you any constant from any existing class/module nesting.

Definitively.

Folks, please keep in mind that the proposed solution from the OP's
posting works only in the global context:

irb(main):001:0> module A
irb(main):002:1> module B
irb(main):003:2> module C
irb(main):004:3> end
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> "A::B::C".split("::").inject(Kernel) {|a,b| a.const_get(b)}
=> A::B::C
irb(main):008:0> module A
irb(main):009:1> p "B::C".split("::").inject(Kernel) {|a,b| a.const_get(b)}
irb(main):010:1> end
NameError: uninitialized constant Kernel::B
        from (irb):9:in `const_get'
        from (irb):9
        from (irb):10:in `inject'
        from (irb):9:in `each'
        from (irb):9:in `inject'
        from (irb):9
        from :0
irb(main):011:0> module A
irb(main):012:1> p "B::C".split("::").inject(self) {|a,b| a.const_get(b)}
irb(main):013:1> end
A::B::C
=> nil

There needs to be at least a bit more logic to take care of nested
scopes and constants with leading "::". Having said that it's probably
wise to put the method in class Module, like:

class Module
  def deref(name)
    parts = name.split "::"
    start = self

    if parts.first == ""
      # start with global scope
      start = Kernel
      parts.shift
    end

    parts.inject(start) {|a,b| a.const_get(b)}
  end
end

class Object
  def deref(name)
    self.class.deref(name)
  end
end

irb(main):021:0> module A
irb(main):022:1> module B
irb(main):023:2> module C
irb(main):024:3> end
irb(main):025:2> end
irb(main):026:1> end
=> nil
irb(main):027:0> deref "A::B::C"
=> A::B::C
irb(main):028:0> module A
irb(main):029:1> p deref("B::C")
irb(main):030:1> p deref("::A::B")
irb(main):031:1> end
A::B::C
A::B
=> nil


Kind regards

robert