dsg
dsg

Reputation: 13004

Ruby idiom: method call or else default

What's the proper way of doing this in Ruby?

def callOrElse(obj, method, default)
  if obj.respond_to?(method) 
     obj.__send__(method)
  else 
     default
  end
end

Upvotes: 6

Views: 1056

Answers (4)

Reggie Escobar
Reggie Escobar

Reputation: 99

You can do something like this:

object&.method(n) || 'default'

the '&' acts as a Maybe here. Maybe it has something, maybe it doesn't. Of course, if it doesn't, it will just return nil and would not run the method that comes after it.

Upvotes: -1

Phrogz
Phrogz

Reputation: 303251

Because it hasn't been offered as an answer:

result = obj.method rescue default

As with @slhck, I probably wouldn't use this when I knew there was a reasonable chance that obj won't respond to method, but it is an option.

Upvotes: 5

tokland
tokland

Reputation: 67870

So you want something similar to x = obj.method || default? Ruby is an ideal language to build your own bottom-up constructions:

class Object
  def try_method(name, *args, &block)
    self.respond_to?(name) ? self.send(name, *args, &block) : nil     
  end
end

p "Hello".try_method(:downcase) || "default" # "hello"
p "hello".try_method(:not_existing) || "default" # "default"

Maybe you don't like this indirect calling with symbols? no problem, then look at Ick's maybe style and use a proxy object (you can figure out the implementation):

p "hello".maybe_has_method.not_existing || "default" # "default"

Side note: I am no OOP expert, but it's my understanding that you should know whether the object you are calling has indeed such method beforehand. Or is nil the object you want to control not to send methods to? Im this case Ick is already a nice solution: object_or_nil.maybe.method || default

Upvotes: 3

slhck
slhck

Reputation: 38691

I'd probably go for

obj.respond_to?(method) ? obj.__send__(method) : default

Upvotes: 2

Related Questions