如果定义了方法,则"分配方法结果的快捷方式,否则为默认值"在Ruby中

时间:2015-05-08 22:16:39

标签: ruby

在Ruby分配中可以检查方法是否返回值,如果没有,则提供默认值:

my_var = foo() || my_default

是否有类似的快捷方式来检查方法是否存在?也就是说,这是一个较短的版本:

my_var = if defined? foo
           foo()
         else
           my_default
         end

或者这个:

my_var = defined?(foo) ? foo() : my_default

后一个版本不是可怕的,但是当方法和变量名称以及默认值变得更长时,它会变得难以处理:

resource_list = defined?(resource_list_override) ? resource_list_override() : [Resource.new(uri: 'http://example.org/'), Resource.new(uri: 'http://example.com/')]

如果存在这样的事情,我想将其归结为不重复方法名称的内容。

2 个答案:

答案 0 :(得分:2)

默认情况下,没有一种干净的方法,但您可以实现与presence类似的功能。

class Object
  def call_default(method_name, default)
    self.respond_to?(method_name) ? self.send(method_name) : default
  end
end

my_var = call_default :foo, my_default

或者,如果您需要向该方法发送参数:

class Object
  def call_default(method_name, *args, default)
    self.respond_to?(method_name) ? self.send(method_name, *args) : default
  end
end

my_var = call_default :foo, 'bar', 'baz', my_default

答案 1 :(得分:0)

你可以写一个小方法来做到这一点......

def do_or_default(method, default)
  eval(method.to_s)
rescue NameError
  return default
end

将要测试的方法作为符号传递。

def return_hello
  "hello"
end

# method return_hello exists...
p do_or_default(:return_hello, "goodbye")
=> "hello"

# method return_howdy doesn't exist...
p do_or_default(:return_howdy, "goodbye")
=> "goodbye" 

通常应避免使用eval,但有时无法帮助他们。如果您的用户提供了要测试的方法,则您不想使用此功能。