We solved this issue by attempting to create the specific presenter and rescuing with the base presenter.
klass = " _presenter".camelize.constantize rescue Presenter
@presenter = klass.new
Inline rescues promote concise code, but they shouldn't be overused to create overly complex lines of code. For example, I probably could have combined the two lines above into one line, but that would be a bit much to digest in my opinion.
In the example we attempt to create the class using constantize, but if an error (like uninitialized constant) occurs we rescue with the base Presenter class. Either way, the result is assigned to the klass local variable.
I'm a fan of inline rescue's as well, but I think its important to use them judiciously. In your example you're executing a very specific set of methods and there's not many types of errors that could be thrown...which creates a great place to use an inline rescue. The flip side that I've seen is that people will do things like:
ReplyDeleteobj = some.complex.calls.and.logic rescue nil
where the chain of events could do anything from throw an ActiveRecord error to a LoadError, or more. The more responsible thing IMHO in places like that is to be specific about what error you're catching, which will force you to split things out over multiple lines in a block format.
Here's a line that I include in every project..
ReplyDeletexml.append! begin render( :partial => "layouts/#{controller.controller_name}" ) rescue yield end
I use builder for templates and append! is a method I added that works just like << except adds indentation. So render the controller template, or just show the action if there isn't one.
I don't use inline rescue much, but it's nice to have sometimes. :)
Hi Jay,
ReplyDeleteDid you consider using const_defined? instead of rescue? "Exceptions are for Exceptional circumstances" and all that.
his reminds me of on error resume next in vb :D
ReplyDeleteHey Toby,
ReplyDeleteYeah, that's probably a better solution. Rescuing was the first thing that came to mind and it just worked so I never gave it another thought.
Cheers, Jay
you wanted to express it as a single line - Easy and great. Anyway, I always have a twitch on my left eye when I see this "klass" idiom. Here:
ReplyDelete@presenter = ("#{action}_presenter".camelize.constantize rescue Presenter).new
Parenthesis are a great tool, and often underused in Ruby :)
Wow I like the parentheses mentioned in the comments. Suppose I should use more of those.
ReplyDeleteI'm a fan of inline rescue, too, though...they're a little scary. andand might help out in the case of it returning nil.
Take care.
-R