我可以在Ruby 2.x中需要命名参数吗?

Ruby 2.0正在添加命名参数,如下所示:

def say(greeting: 'hi') puts greeting end say # => puts 'hi' say(greeting: 'howdy') # => puts 'howdy' 

我如何使用命名参数而不给予默认值,以便它们是必需的?

在Ruby 2.0.0中没有具体的方法,但是可以使用Ruby 2.1.0 ,语法如def foo(a:, b:) ...

在Ruby 2.0.x中,可以通过放置任何引发exception的expression式来强制执行它,例如:

 def say(greeting: raise "greeting is required") # ... end 

如果你打算做这么多(不能使用Ruby 2.1+),你可以使用一个辅助方法,如:

 def required method = caller_locations(1,1)[0].label raise ArgumentError, "A required keyword argument was not specified when calling '#{method}'" end def say(greeting: required) # ... end say # => A required keyword argument was not specified when calling 'say' 

在当前时刻(Ruby 2.0.0-preview1),您可以使用以下方法签名:

 def say(greeting: greeting_to_say) puts greeting end 

greeting_to_say只是一个占位符,如果你给参数提供了一个参数,它将不会被评估。 如果你不传递它(调用只是say() ),ruby将提高错误:

 NameError: undefined local variable or method `greeting_to_say' for (your scope) 

但是,这个variables并没有被绑定到任何东西上,就我所知,不能从你的方法内部引用。 您仍将使用greeting作为局部variables来引用传入的命名参数。

如果你真的要这样做 ,我会build议使用def say(greeting: greeting)这样错误信息会引用你给你的参数的名字。 在上面的例子中,我只select了不同的部分来说明ruby在错误信息中使用了什么,因为没有提供参数给所需的命名参数。

切线,如果你打电话say('hi')ruby会引发ArgumentError: wrong number of arguments (1 for 0) ,我认为有点混淆,但它只是预览1。

结合@awendt和@Adam的解决scheme,

 def say(greeting: ->{ raise ArgumentError.new("greeting is required") }.call) puts greeting end 

你可以用这样的东西干这个:

 def required(arg) raise ArgumentError.new("required #{arg}") end def say(greeting: required('greeting')) puts greeting end 

结合@ Marc-Andre的解决scheme: https : //gist.github.com/rdp/5390849

怎么样:

 def say(greeting: nil) greeting or raise ArgumentError puts greeting end say # => raises ArgumentError say(greeting: 'howdy') # => puts 'howdy' 

除此之外,这将是困难的。 根据这个网站 ,关键字参数“被命名为具有默认值的参数”。

在Ruby 2.3中,我可以做到

 def say(greeting:) puts greeting end