How do I turn a string into a class name, but only if that class already exists?
If Amber is already a class, I can get from a string to the class via:
Object.const_get("Amber")
or (in Rails)
"Amber".constantize
But either of these will fail with NameError: uninitialized constant Amber
if Amber is not already a class.
My first thought is to use the defined?
method, but it doesn't discriminate between classes that already exist and those that don't:
>> defined?("Object".constantize)
=> "method"
>> defined?("AClassNameThatCouldNotPossiblyExist".constantize)
=> "method"
So how do I test if a string names a class before I try to convert it? (Okay, how about a begin
/rescue
block to catch NameError errors? Too ugly? I agree...)
It would appear that all the answers using the
Object.const_defined?
method are flawed. If the class in question has not been loaded yet, due to lazy loading, then the assertion will fail. The only way to achieve this definitively is like so:I've created a validator to test if a string is a valid class name (or comma-separated list of valid class names):
Another approach, in case you want to get the class too. Will return nil if the class isn't defined, so you don't have to catch an exception.
How about
const_defined?
?Remember in Rails, there is auto-loading in development mode, so it can be tricky when you are testing it out:
In rails it's really easy:
Inspired by @ctcherry's response above, here's a 'safe class method send', where
class_name
is a string. Ifclass_name
doesn't name a class, it returns nil.An even safer version which invokes
method
only ifclass_name
responds to it: