Robert Klemme
8/21/2007 2:41:00 PM
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