Ruby中没有命名参数?

时间:2012-03-08 03:30:40

标签: ruby parameters named-parameters

这很简单,我不敢相信它抓住了我。

def meth(id, options = "options", scope = "scope")
  puts options
end

meth(1, scope = "meh")

-> "meh"

我倾向于使用哈希作为参数选项,因为这是牧群的做法 - 它非常干净。我认为这是标准。今天,经过大约3个小时的追捕,我追溯到这个宝石的一个错误我碰巧正在使用假设命名参数将被尊重。他们不是。

所以,我的问题是:在Ruby(1.9.3)中,命名参数是否正式未被尊重,或者这是我缺少的东西的副作用?如果不是,为什么不呢?

4 个答案:

答案 0 :(得分: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"

命名参数没有支持*(参见下面的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"

等等。但是,由于缺少命名参数,它们都是变通方法。


编辑(2013年2月15日):

*嗯,at least until the upcoming 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"

答案 1 :(得分:5)

我认为这里发生了两件事:

  1. 您正在名为“scope”的方法上定义一个参数,其默认值为“scope”
  2. 当您调用该方法时,您将值“meh”分配给名为“scope”的新 local 变量,该变量与您正在调用的方法的参数名称无关。

答案 2 :(得分:3)

尽管Ruby语言不支持命名参数,但您可以通过将函数参数传递给哈希来模拟它们。例如:

def meth(id, parameters = {})
  options = parameters["options"] || "options"
  scope = parameters["scope"] || "scope"

  puts options
end

可以使用如下:

meth(1, scope: "meh")

您现有的代码只是指定一个变量,然后将该变量传递给您的函数。有关详细信息,请参阅:http://deepfall.blogspot.com/2008/08/named-parameters-in-ruby.html

答案 3 :(得分:0)

Ruby没有命名参数。

示例方法定义具有默认值的参数。

调用站点示例为名为 scope 的调用者作用域本地变量赋值,然后将其值(meh)传递给选项参数。