Ruby 2.0 中的命名参数(关键字参数)

来源:互联网 发布:卧蚕阿姨 淘宝店 编辑:程序博客网 时间:2024/05/17 22:00

来自维基百科:在计算机编程语言中,命名参数或者叫做关键字参数指的是计算机语言支持为函数调用的每个参数定义一个专门的名称。

现在 (我指的是 Ruby <= 1.9.3) 你可以通过传递参数的哈希值到指定方法来模仿这个行为:

1def foo(options = {})
2  puts "#{options[:bar]} #{options[:buz]}"
3end
4 
5foo(bar: 'bar', buz: 'buz'# => 'bar buz'

我敢打赌你一定见过很多这种用法,但主要的问题是这种方法你很难轻松地为某个参数设置一个默认值,当然你可以这样处理:

1def foo(options = {})
2  options = {bar: 'bar'}.merge(options)
3  puts "#{options[:bar]} #{options[:buz]}"
4end
5 
6foo(buz: 'buz'# => 'bar buz'

但看起来不是一种漂亮的解决方法,那么 Ruby 2.0 会对此作何改变呢?从 Ruby 的 CHANGELOG可以看到:

实现了关键字参数,该功能将在 2.0 中提供,详细的方案还在讨论中。

听起来很有希望,你将可能在 Ruby 的语法中看到关键字参数,那么该如何使用呢?这里有很多的测试,我们找一些出来看看:

只包含关键字参数:
1def foo(str: "foo", num: 424242)
2  [str, num]
3end
4 
5foo(str: 'buz', num: 9#=> ['buz', 9]
6foo(str: 'bar'# => ['bar', 424242]
7foo # => ['foo', 424242]
8foo(bar: 'buz'# => ArgumentError

正如你所看到的,你不需要做合并或者其他额外的工作来实现参数默认值,而如果你给的参数不匹配将会收到一个 ArgumentError 错误,像 Rails 通过 assert_valid_keys 方法扩展的 Hash 类

使用关键字参数的普通参数

1def foo(x, str: "foo", num: 424242)
2  [x, str, num]
3end
4 
5foo(13#=> [13, 'foo', 424242]
6foo(13, str: 'bar'#=> [13, 'bar', 424242]

关键字参数和选项

1def foo(str: "foo", num: 424242, **options)
2  [str, num, options]
3end
4 
5foo #=> ['foo', 424242, {}]
6foo(check: true# => ['foo', 424242, {check: true}]

你看到了又一个 ** 的新字符串,允许你传递哈希到方法:

1def foo(str: "foo", num: 424242, options = {})
2  [str, num, options]
3end

这将无法运行,你会收到错误 syntax error, unexpected ')', expecting end-of-input.

也可以在块中运行

1define_method(:foo) {|str: "foo", num: 424242| [str, num] }

还是让我们翘首以待 Ruby 2.0 的发布把。


转自:http://www.oschina.net/question/12_72725?from=20121014

原创粉丝点击