缩短传递给方法的参数的最佳方法

时间:2016-08-04 05:28:33

标签: ruby

将一长串变量作为参数传递给方法的最佳方法是什么?

def foo(a,b,c,d,e,f) # Could this be shorter? No?
  puts f + " loves " + e
  # dad loves you
end

egg = "Chicken"
girl = "Money"
car = "luxury"
rich = "poor"
me = "you"
mom = "dad"

foo(egg, girl, car, rich, me, mom)

foo(a..f)的内容吗?是的,如果可能的话,它不会工作,但正在寻找简短而整洁的东西。

2 个答案:

答案 0 :(得分:1)

documentation

中描述了调用方法的所有可能方法
egg = "Chicken"
girl = "Money"
car = "luxury"
rich = "poor"
me = "you"
mom = "dad"

选项1.使用splat

def foo(*args)
  puts "#{args[-1]} loves #{args[-2]}"
end
foo(*[egg, girl, car, rich, me, mom])  # dad loves you

选项2.使用双splat

def foo(**params)
  puts "#{params[:mom]} loves #{params[:me]}"
end
foo(me: me, mom: mom)  # dad loves you
双splat默认值:
def foo(me: 'you', mom:,  **params)
  puts "#{mom} loves #{me}"
end
foo(mom: mom)  # dad loves you

答案 1 :(得分:0)

Splat(*)运算符

方法可以通过在参数前加上*(splat)或**(双splat)运算符来获取任意数量的参数。当方法定义中未知确切的参数数量时,这非常有用。

首先让我们看一下*(splat)运算符。通过前缀为*的参数传递的所有参数都自动存储在数组中。

def list_masters *names
    print names
end

# Call the method and pass it three arguments
list_masters "Shunryu Suzuki", "Thich Nhat Hanh", "Kodo Sawaki"
Output:
["Shunryu Suzuki", "Thich Nhat Hanh", "Kodo Sawaki"]

注意输出是一个数组。

Ruby中的splat运算符还有其他用途,例如在将数组传递给方法时展开数组,将值强制转换为数组并解构数组,但这些不在本文的讨论范围之内。

双splat(**)运算符

现在让我们看看**(双splat)运算符。它是在Ruby 2.0中引入的,并且以与单个splat运算符类似的方式工作,除了它将参数存储在散列而不是数组中。我们来试试吧:

def meditate **details
    print details
end

# Call the method and pass it three arguments
meditate mat: "zabuton", cushion: "zafu", practice: "shikantaza", time: 40
Output:
{:mat=>"zabuton", :cushion=>"zafu", :practice=>"shikantaza", :time=>40}

请注意,输出是一个哈希值。

前缀为double splat的参数只接受关键字参数,例如分钟:40或冥想:“zazen”。

混合*和**运算符

如果方法同时包含单个splat参数和双splat参数,则前缀为*的参数将采用非关键字参数,并且将使用前缀为**的参数获取哈希参数。例如:

def meditate *practices, **details
    puts "Practices: #{practices}"
    puts "Details: #{details}"
end

meditate"zazen", "kinhin", duration: 40, time: "morning"
Output:
Practices: ["zazen", "kinhin"]
Details: {:duration=>40, :time=>"morning"}

请注意,通过* practices参数传递的参数已插入到数组中,通过** details参数传递的参数存储在哈希中。

当方法包含*和**参数时,应首先提供所有位置参数,然后提供关键字参数。如果我们尝试调用上面的方法并首先提供关键字参数,则会抛出语法错误:

meditate time: "morning", duration: 40, "zazen", "kinhin"
Output:
SyntaxError: (irb):59: syntax error, unexpected ',', expecting =>
meditate time: "morning", duration: 40, "zazen", "kinhin"
                                            ^