ruby - Ruby 中没有命名参数?

标签 ruby parameters named-parameters

这太简单了,我简直不敢相信它捕获了我。

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

meth(1, scope = "meh")

-> "meh"

我倾向于使用散列作为参数选项,因为这是大众的做法——而且非常干净。我以为这是标准。今天,经过大约 3 小时的错误搜索,我找到了一个错误到我碰巧使用的这个 gem,assumes 命名参数将被接受。他们不是。

所以,我的问题是:命名参数在 Ruby (1.9.3) 中是否正式不受尊重,或者这是我遗漏了什么的副作用?如果不是,为什么不呢?

最佳答案

实际发生了什么:

# 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"

关于ruby - Ruby 中没有命名参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9612499/

相关文章:

scala - 省略一些隐式参数

c# - 使用命名参数动态调用方法

ruby - 生成街道 map 图像

ruby-on-rails - 根据用户代理和/或 ip 更改重置 session 。带 Devise 的 Rails

ruby - 以元编程方式定义采用关键字参数的 Ruby 方法?

ruby - 有效检查整个帐户的未读计数

Swift UIGestureRecognizer 表示法

symfony - 获取 AppKernel.php 中的 parameters.yml 参数

c# - cmd.Parameters.AddWithValue() 当值为空时?

python - 在给定条件的情况下,是否有一种简洁的(Pythonic?)方法在Python中使用命名参数默认值?