Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
like image 411
dsg Avatar asked Jan 30 '11 07:01

dsg


People also ask

What is a method in Ruby?

A method in Ruby is a set of expressions that returns a value. With methods, one can organize their code into subroutines that can be easily invoked from other areas of their program. Other languages sometimes refer to this as a function. A method may be defined as a part of a class or separately.

What is call method in Rails?

It is used to call back a piece of code that has been passed around as an object.

What does .call do in Ruby?

The purpose of the . call method is to invoke/execute a Proc/Method instance.


Video Answer


3 Answers

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.

like image 185
Phrogz Avatar answered Nov 15 '22 06:11

Phrogz


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

like image 28
tokland Avatar answered Nov 15 '22 06:11

tokland


I'd probably go for

obj.respond_to?(method) ? obj.__send__(method) : default
like image 31
slhck Avatar answered Nov 15 '22 07:11

slhck