我可以在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