使用或不使用参数调用泛型函数

时间:2013-05-15 13:23:32

标签: ruby-on-rails ruby

我的代码看起来像这样:

def my_function(obj)
  if obj.type == 'a'
    return [:something]
  elsif obj.type == 'b'
    return []
  elsif obj.type == 'c'
    return [obj]
  elsif obj.type == 'd'
    return [obj]*2
  end
end

我想将所有这些if...elsif块分成如下函数:

def my_function_with_a
  return [:something]
end

def my_function_with_b
   return []
end

def my_function_with_c(a_parameter)
  return [a_parameter]
end

def my_function_with_d(a_parameter)
  return [a_parameter] * 2
end

我用

调用这些函数
def my_function(obj)
  send(:"my_function_with_#{obj.type}", obj)
end

问题是某些功能需要参数,而其他功能则不需要。我可以轻松定义def my_function_with_a(nothing=nil),但我确信有更好的解决方案可以做到这一点。

@Dogbert对arity有个好主意。我有这样的解决方案:

def my_function(obj)
  my_method = self.method("my_function_with_#{obj.type}")
  return (method.arity.zero? ? method.call : method.call(obj))
end

5 个答案:

答案 0 :(得分:2)

def foo(*args)
  [ 'foo' ].push(*args)
end

>> foo
=> [ 'foo' ]
>> foo('bar')
=> [ 'foo', 'bar' ]
>> foo('bar', 'baz')
=> [ 'foo', 'bar', 'baz' ]

答案 1 :(得分:2)

检查如何在Ruby中调用方法,为此,我将向您推荐这两个资源:wikibooksenter link description here

对可选参数进行特别说明,您可以在其中定义如下方法:

def method(*args)
end

然后你打电话给它:

  

方法

     

方法(ARG1)

     

方法(arg1,arg2)

答案 2 :(得分:1)

将您的功能更改为:

def my_function_with_foo(bar=nil)
  if bar
    return ['foo', bar]
  else
    return ['foo']
  end
end

现在以下内容都有效:

send(:"my_function_with_#{foo_bar}")
=> ['foo']
send(:"my_function_with_#{foo_bar}", "bar")
=> ['foo', 'bar']

如果你不想使用if/else并且你确定你在数组中永远不需要nil,你也可以这样写:

def my_function_with_foo(bar=nil)
  return ['foo', bar].compact
end

答案 3 :(得分:1)

def my_function(obj)
  method = method("my_function_with_#{obj.type}")
  method.call(*[obj].first(method.arity))
end

答案 4 :(得分:0)

您可以使用默认值

def fun(a_param = nil)
    if a_param
        return ['raboof',a_param]
    else
        return ['raboof']
    end
end

...或

def fun(a_param : nil)
    if a_param
        return ['raboof',a_param]
    else
        return ['raboof']
    end
end

如果你有多个参数,后者很有用,因为现在当你调用它时,你可以直接传递那些重要的参数。

fun(a_param:"Hooray")