Convert a string to class
Change a string into a class reference in ruby
How to convert a string to class in Ruby?
First off, a string in ruby has a variety of methods on it to change the format to another format fairly easily. The main conversion methods are from a snake_case
string to a CamelCase
string. Class names in ruby are actually represented as a constant in CamelCase form.
Start with converting to CamelCase string:
my_class_string = "my_class"
camel_case_string = my_class_string.camelize
Next we have to make sure it is a singular class name. For instance, say someone passes in a class as records
you’d want to convert it to record
. Luckily, that is fairly simple as illustrated below.
camel_case_string = camel_case_string.singularize
The main conversion from a string to a class will happen with the method constantize
. The method constantize
will take a string and find a corresponding constant value defined in the ruby runtime. Remember what was described above, that a class is defined as a constant in ruby. So, as we invoke constantize
on a string ruby will find the class mapped to the class name.
The whole example will look like this in a streamlined form:
my_class_string = "my_class"
my_class_string.camelize.singularize.constantize
Tip: This will also work for modules
Also note, camelize
, constantize
and singularize
are part of ActiveSupport. In order to run this in a non-rails environment, add this to you ruby application:
class String
def camelize
self.split("_").each {|s| s.capitalize! }.join("")
end
def constantize
names = self.split('::')
names.shift if names.empty? || names.first.empty?
names.inject(Object) do |constant, name|
if constant == Object
constant.const_get(name)
else
candidate = constant.const_get(name)
next candidate if constant.const_defined?(name, false)
next candidate unless Object.const_defined?(name)
# Go down the ancestors to check it it's owned
# directly before we reach Object or the end of ancestors.
constant = constant.ancestors.inject do |const, ancestor|
break const if ancestor == Object
break ancestor if ancestor.const_defined?(name, false)
const
end
# owner is in Object, so raise
constant.const_get(name, false)
end
end
end
end
The above is derived from ActiveSupport’s Inflector methods.