The following example fails
class A
class B
end
end
p Object.const_get 'A' # => A
p Object.const_get 'A::B' # => NameError: wrong constant name A::B
UPDATE
Questions about the topic asked earlier:
- Cast between String and Classname
- Ruby String#to_class
- Get a class by name in Ruby?
The last one gives a nice solution which can be evolved into
class String
def to_class
self.split('::').inject(Object) do |mod, class_name|
mod.const_get(class_name)
end
end
end
class A
class B
end
end
p "A::B".to_class # => A::B
You'll have to manually "parse" the colons yourself and call const_get
on the parent module/class:
ruby-1.9.1-p378 > class A
ruby-1.9.1-p378 ?> class B
ruby-1.9.1-p378 ?> end
ruby-1.9.1-p378 ?> end
=> nil
ruby-1.9.1-p378 > A.const_get 'B'
=> A::B
Someone has written a qualified_const_get
that may be of interest.
Here is Rails' constantize
method:
def constantize(camel_cased_word)
names = camel_cased_word.split('::')
names.shift if names.empty? || names.first.empty?
constant = Object
names.each do |name|
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
end
constant
end
See, it starts at the Object
on top of it all, then uses each name in between the double semicolons as a stepping stone to get to the constant you want.
Extlib provides a full_const_get
method, which does just this.
http://github.com/datamapper/extlib/blob/master/lib/extlib/object.rb#L67
You could either include extlib, or copy this implementation and use it yourself (assuming the licensing is compatible with whatever you're using it for)
You can do this with eval also which works in some cases where const_get won't.
There's a good article on this here:
http://blog.sidu.in/2008/02/loading-classes-from-strings-in-ruby.html#.T8j88HlYtXc