Reputation: 1448
Is there some hidden Ruby/Rails-magic for simply calling a method only if it exists?
Lets say I want to call
resource.phone_number
but I don't know beforehand if resource responds to phone_number
. A way to do this is
resource.phone_number if resource.respond_to? :phone_number
That's not all that pretty if used in the wrong place. I'm curious if something exists that works more along the lines of how try
is used (resource.try(:phone_number)
).
Upvotes: 76
Views: 83675
Reputation: 357
I can't speak for the efficiency, but something like...
Klass.methods.include?(:method_name)
works for me in Rails 4
Upvotes: 1
Reputation: 1810
If A.c
is defined and A.a
and A.b
are not, you can do A.a rescue A.b rescue A.c
and it will work like a charm. You will be breaking some silly rules, though.
Upvotes: -2
Reputation: 121010
If you are not satisfied with the standard ruby syntax for that, you are free to:
class Object
def try_outside_rails(meth, *args, &cb)
self.send(meth.to_sym, *args, &cb) if self.respond_to?(meth.to_sym)
end
end
Now:
resource.try_outside_rails(:phone_number)
will behave as you wanted.
Upvotes: 46
Reputation: 20182
I would try defined?
(http://ruby-doc.org/docs/keywords/1.9/Object.html#defined-3F-method). It seems to do exactly what you are asking for:
resource.phone_number if defined? resource.phone_number
Upvotes: 18
Reputation: 592
I know this is very old post. But just wanted to know if this could be a possible answer and whether the impact is the same .
resource.try(:phone_number) rescue nil
Thanks
Upvotes: 13