-1

我有一个看起来像这样的代码:

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
4

5 回答 5

3

检查如何在 Ruby 中调用方法,为此我将向您推荐这两个资源:wikibooks在此处输入链接描述

特别注意可选参数,您可以在其中定义如下方法:

def method(*args)
end

然后你这样称呼它:

方法

方法(arg1)

方法(arg1,arg2)

于 2013-05-15T13:43:09.403 回答
2
def foo(*args)
  [ 'foo' ].push(*args)
end

>> foo
=> [ 'foo' ]
>> foo('bar')
=> [ 'foo', 'bar' ]
>> foo('bar', 'baz')
=> [ 'foo', 'bar', 'baz' ]
于 2013-05-15T13:40:51.570 回答
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
于 2013-05-15T13:28:14.100 回答
1
def my_function(obj)
  method = method("my_function_with_#{obj.type}")
  method.call(*[obj].first(method.arity))
end
于 2013-05-15T14:38:45.240 回答
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")
于 2013-05-15T13:31:39.247 回答