Frans
Frans

Reputation: 1448

Call method only if it exists

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

Answers (5)

Stephen
Stephen

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

nroose
nroose

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

Aleksei Matiushkin
Aleksei Matiushkin

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

jmarceli
jmarceli

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

Bhavya
Bhavya

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

Related Questions