Our application uses a number of environments so we can experiment with settings without breaking things. In a typical controller action, I have something like this:
def some_action
...
if @foo.development_mode == 'Production'
@settings = SomeHelper::Production.lan(bar)
elsif @foo.development_mode == 'Beta'
@settings = SomeHelper::Beta.lan(nas)
elsif @foo.development_mode == 'Experimental'
@settings = SomeHelper::Experimental.lan(nas)
end
...
end
Since we have dozens of these, I figured I could try and dry things up with something like this:
@settings = "SomeHelper::#{@foo.development_mode}.lan(bar)"
Which obviously doesn’t work – I just get:
"NasHelper::Production.lan(bar)"
How can I reduce this down or do I have to stick with what I’ve got??
If your concern is that you’re ending up with a String rather than the object, you can use
String.constantize(Rails only, with standard Ruby you’d have to implement this; it uses Object.const_get(String))Another option would be
.const_get(e.g.Object.const_get(x)where x is your string), you it doesn’t, on its own, nest correctly, so you would have to split at “::”, etc.Also, there’s the option of using
evalto evaluate the String.But note:
evalshould be used with great care (it’s powerful), or not at all.Edit:
This means that instead of:
You could run:
Useful Sources:
http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-constantize
http://www.ruby-forum.com/topic/183112
http://blog.grayproductions.net/articles/eval_isnt_quite_pure_evil