Joh*_*tta 32 ruby parameters named-parameters
这很简单,我不敢相信它抓住了我.
def meth(id, options = "options", scope = "scope")
puts options
end
meth(1, scope = "meh")
-> "meh"
Run Code Online (Sandbox Code Playgroud)
我倾向于使用哈希作为参数选项,因为它是牧群的做法 - 它非常干净.我认为这是标准.今天,经过大约3个小时的寻找bug之后,我追踪到了一个错误,我碰巧正在使用这个假设命名参数将被尊重.他们不是.
所以,我的问题是:在Ruby(1.9.3)中,命名参数是否正式不受尊重,或者这是我缺少的一个副作用?如果他们不是,为什么不呢?
bry*_*mck 38
实际发生了什么:
# Assign a value of "meh" to scope, which is OUTSIDE meth and equivalent to
# scope = "meth"
# meth(1, scope)
meth(1, scope = "meh")
# Ruby takes the return value of assignment to scope, which is "meh"
# If you were to run `puts scope` at this point you would get "meh"
meth(1, "meh")
# id = 1, options = "meh", scope = "scope"
puts options
# => "meh"
Run Code Online (Sandbox Code Playgroud)
命名参数没有支持*(参见下面的2.0更新).你所看到的只是分配"meh"给scope作为options值传递的结果meth.当然,该任务的价值是"meh".
有几种方法可以做到:
def meth(id, opts = {})
# Method 1
options = opts[:options] || "options"
scope = opts[:scope] || "scope"
# Method 2
opts = { :options => "options", :scope => "scope" }.merge(opts)
# Method 3, for setting instance variables
opts.each do |key, value|
instance_variable_set "@#{key}", value
# or, if you have setter methods
send "#{key}=", value
end
@options ||= "options"
@scope ||= "scope"
end
# Then you can call it with either of these:
meth 1, :scope => "meh"
meth 1, scope: "meh"
Run Code Online (Sandbox Code Playgroud)
等等.但是,由于缺少命名参数,它们都是变通方法.
*好吧,至少在即将推出的支持关键字参数的Ruby 2.0之前!截至本文撰写时,它正在发布候选版本2,即官方发布之前的最后版本.虽然您需要了解上述方法以使用1.8.7,1.9.3等,但现在可以使用更新版本的方法有以下选项:
def meth(id, options: "options", scope: "scope")
puts options
end
meth 1, scope: "meh"
# => "options"
Run Code Online (Sandbox Code Playgroud)
我想这里发生了两件事情: