如何在Ruby中为splat参数设置默认值

时间:2021-02-17 22:31:01

Setting a default value for a splat argument gives an error:

为splat参数设置默认值会产生错误:

1.9.3-p374 :001 > def a b, *c = nil
1.9.3-p374 :002?>   end
SyntaxError: (irb):1: syntax error, unexpected '=', expecting ';' or '\n'
def a b, *c = nil
             ^
    from /Users/me/.rvm/rubies/ruby-1.9.3-p374/bin/irb:16:in `<main>'

Some variations I tried that don't work either:

我试过的一些变化不起作用:

1.9.3-p374 :003 > def a b, *c = []
1.9.3-p374 :005 > def a b, (*c) = nil
1.9.3-p374 :007 > def a b, (*c = [])
1.9.3-p374 :009 > def a b, (*c = [1,2,3])
1.9.3-p374 :011 > def a b, *c = [1,2,3]

I don't see an indeterminacy issue here, so it seems like it should be possible.

我在这里看不到不确定性问题,所以看起来应该是可能的。

Related: Why non-explicit splat param plus default param is wrong syntax for method definition in Ruby 1.9?

相关:为什么非显式splat参数加上默认参数是Ruby 1.9中方法定义的错误语法?

4 个解决方案

#1


6  

Your attempted usage is counter the conventions around splat usage. Splats are supposed (at least in Ruby) to take up all extra (0, 1 or more) values.

您的尝试使用是违反splat使用的惯例。假设Splats(至少在Ruby中)占用所有额外的(0,1或更多)值。

If you know that you want the second value in your method arguments list to have a default value, you could take it out of the splat and list it just before the splat with a default value like this:

如果您知道您希望方法参数列表中的第二个值具有默认值,则可以将其从splat中取出并在splat之前使用默认值列出它,如下所示:

def a b, c=nil, *d 
  # rest of code omitted
end

EDIT: To make the answer to your question of why it doesn't work perfectly clear. It's a design decision by the language designer. Matz never intended the splat operator to work with defaults. This seems pretty sensible to me since it is intended to be used for catching an indeterminate number of variables and because the method I described reads more clearly than the possibilities you described and because all of the problems your examples solve are solvable in other ways.

编辑:回答你的问题为什么它不能完全清楚。这是语言设计师的设计决定。 Matz从未打算让splat运算符使用默认值。这对我来说似乎很合理,因为它旨在用于捕获不确定数量的变量,因为我描述的方法比你描述的可能性读得更清楚,因为你的例子解决的所有问题都可以通过其他方式解决。

#2


2  

You could set the default value in the method itself knowing that the default splat returns an empty array.

您可以在方法本身中设置默认值,因为默认splat返回一个空数组。

def test(a, *b)
  b = "default b" if b == [] # edited as per Tin Man's recommendation
  puts [a, b].inspect
end

test("Test", 1, 2)
# => ["Test", [1, 2]]
test("Test")
# => ["Test", "default b"]

In Rails, you could check for b.present? as an empty array is considered blank. Hope that helps.

在Rails中,你可以查看b.present吗?作为空数组被视为空白。希望有所帮助。

#3


0  

A splat argument defaults to an empty array, without your having to do anything special.

splat参数默认为空数组,无需执行任何特殊操作。

def a(b, *c)
  c
end

a("foo")
#=> []

#4


0  

This is very convenient:

这很方便:

def initialize(*response_names)
  @response_names = response_names.presence || %w(default values)
end

#1


6  

Your attempted usage is counter the conventions around splat usage. Splats are supposed (at least in Ruby) to take up all extra (0, 1 or more) values.

您的尝试使用是违反splat使用的惯例。假设Splats(至少在Ruby中)占用所有额外的(0,1或更多)值。

If you know that you want the second value in your method arguments list to have a default value, you could take it out of the splat and list it just before the splat with a default value like this:

如果您知道您希望方法参数列表中的第二个值具有默认值,则可以将其从splat中取出并在splat之前使用默认值列出它,如下所示:

def a b, c=nil, *d 
  # rest of code omitted
end

EDIT: To make the answer to your question of why it doesn't work perfectly clear. It's a design decision by the language designer. Matz never intended the splat operator to work with defaults. This seems pretty sensible to me since it is intended to be used for catching an indeterminate number of variables and because the method I described reads more clearly than the possibilities you described and because all of the problems your examples solve are solvable in other ways.

编辑:回答你的问题为什么它不能完全清楚。这是语言设计师的设计决定。 Matz从未打算让splat运算符使用默认值。这对我来说似乎很合理,因为它旨在用于捕获不确定数量的变量,因为我描述的方法比你描述的可能性读得更清楚,因为你的例子解决的所有问题都可以通过其他方式解决。

#2


2  

You could set the default value in the method itself knowing that the default splat returns an empty array.

您可以在方法本身中设置默认值,因为默认splat返回一个空数组。

def test(a, *b)
  b = "default b" if b == [] # edited as per Tin Man's recommendation
  puts [a, b].inspect
end

test("Test", 1, 2)
# => ["Test", [1, 2]]
test("Test")
# => ["Test", "default b"]

In Rails, you could check for b.present? as an empty array is considered blank. Hope that helps.

在Rails中,你可以查看b.present吗?作为空数组被视为空白。希望有所帮助。

#3


0  

A splat argument defaults to an empty array, without your having to do anything special.

splat参数默认为空数组,无需执行任何特殊操作。

def a(b, *c)
  c
end

a("foo")
#=> []

#4


0  

This is very convenient:

这很方便:

def initialize(*response_names)
  @response_names = response_names.presence || %w(default values)
end