Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby中没有命名参数?_Ruby_Parameters_Named Parameters - Fatal编程技术网

Ruby中没有命名参数?

Ruby中没有命名参数?,ruby,parameters,named-parameters,Ruby,Parameters,Named Parameters,这太简单了,我简直不敢相信它抓住了我 def meth(id, options = "options", scope = "scope") puts options end meth(1, scope = "meh") -> "meh" 我倾向于使用散列作为参数选项,只是因为这是羊群的做法——而且非常干净。我以为这是标准。今天,在大约3个小时的bug搜索之后,我发现了一个错误,我碰巧使用了这个gem,它假设命名参数将得到尊重。事实并非如此 那么,我的问题是:命名参数在Ruby(1

这太简单了,我简直不敢相信它抓住了我

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

meth(1, scope = "meh")

-> "meh"
我倾向于使用散列作为参数选项,只是因为这是羊群的做法——而且非常干净。我以为这是标准。今天,在大约3个小时的bug搜索之后,我发现了一个错误,我碰巧使用了这个gem,它假设命名参数将得到尊重。事实并非如此


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

Ruby没有命名参数

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


调用站点示例将一个值分配给调用方的scope局部变量scope,然后将其值(meh)传递给options参数。

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

  • 您正在使用默认值“scope”在名为“scope”的方法上定义参数
  • 调用该方法时,将值“meh”赋给名为“scope”的新局部变量,该变量与所调用方法上的参数名称无关

  • 尽管Ruby语言不支持命名参数,但可以通过散列传递函数参数来模拟它们。例如:

    def meth(id, parameters = {})
      options = parameters["options"] || "options"
      scope = parameters["scope"] || "scope"
    
      puts options
    end
    
    可按如下方式使用:

    meth(1, scope: "meh")
    

    现有代码只是分配一个变量,然后将该变量传递给函数。有关更多信息,请参阅:。

    实际发生的情况:

    # 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”
    分配给
    范围
    作为
    方法中的
    选项
    值传递的结果。当然,该作业的值是
    “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日): *好吧,它支持关键字参数!在写这篇文章时,它出现在候选版本2上,这是正式发布之前的最后一个版本。尽管您需要了解以上方法才能使用1.8.7、1.9.3等,但那些能够使用较新版本的用户现在有以下选项:

    def meth(id, options: "options", scope: "scope")
      puts options
    end
    
    meth 1, scope: "meh"
    # => "options"
    

    是的,这就是我想发生的事情。我从来没有想过,因为我从来没有在Ruby中实际使用过命名参数。我总是用杂烩。然后,当我在这个编码良好的gem中看到它时,我很惊讶。@johnmeta是的,这听起来像是开发人员的一个心理失误。让他(她)知道可能是个好主意,但我不能因为一厢情愿而责怪开发人员是我干的。Github问题。我正在考虑重建它并提交一个pull请求,但我需要先获得项目的动态,所以现在只需要解决它。Ruby 2.0中有关于命名参数的讨论:,没有你。相关:“命名参数如何工作”可能是