Reputation: 105
I need to check whether a object respond to an arbitrary number of methods.
And i'm tired of doing this:
if a.respond_to?(:foo) && a.respond_to?(:bar) && a.respond_to?(:blah)
What would be a more "correct" DRY way to do this?
Upvotes: 0
Views: 371
Reputation:
Try this if you have nothing against monkeypatching:
class Object
def respond_to_all? *meths
meths.all? { |m| self.respond_to?(m) }
end
def respond_to_any? *meths
meths.any? { |m| self.respond_to?(m) }
end
end
p 'a'.respond_to_all? :upcase, :downcase, :capitalize
#=> true
p 'a'.respond_to_all? :upcase, :downcase, :blah
#=> false
p 'a'.respond_to_any? :upcase, :downcase, :blah
#=> true
p 'a'.respond_to_any? :upcaze, :downcaze, :blah
#=> false
UPDATE: using meths.all?
and meths.any?
. @MarkThomas, thanks for refreshing my mind.
UPDATE: fixing responsd
typo.
Upvotes: 2
Reputation: 37517
You can always wrap it in a helper method:
def has_methods?(obj, *methods)
methods.all?{|method| obj.respond_to? method}
end
Upvotes: 3
Reputation: 11904
The 'correct' way (or one of many, anyway), is Tell Don't Ask, meaning that if you're sending the object a message, you expect it to respond without complaining. This is also known as Duck Typing (if it can quack, it's a duck).
I can't give you any specific advice, because you haven't asked a specific question. If you're testing for three different methods it seems like you don't know what kind of object a
is, which can be an interesting case to deal with. Post more code!
Upvotes: 0
Reputation: 21791
Check the Active Support
extension from Rails
.
It has method try. It's hard to say how you can use this method because of lack of context, maybe something like this:
if a.try(:foo) && a.try(:bar) && a.try(:blah)
In order to use this method you should
require 'active_support/core_ext/object/try.rb'
Also check my version of this method the tryit:
Upvotes: 0