develop with

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.

comments powered by Disqus

Want to see a topic covered? create a suggestion

Get more developer references and books in the developwith store.