什么是期权哈希?

col*_*est 29 ruby hash options

有人请解释选项哈希吗?我正在从testfirst.org学习ruby课程.练习10(temperature_object)需要选项哈希的知识.

Ser*_*sev 49

Options hash是一个很好的概念,由ruby解析器的一个特性启用.比如说,你有一个带有一些必需参数的方法.您也可以传递一些可选参数.随着时间的推移,您可以添加更多可选参数或删除旧参数.要使方法声明保持干净和稳定,您可以在哈希中传递所有这些可选参数.这样的方法看起来像这样:

def foo(arg1, arg2, opts = {})
  opts.to_s # just return a string value of opts
end
Run Code Online (Sandbox Code Playgroud)

所以它有两个必需值和最后一个参数,默认值为hash.如果您没有要传递的任何可选参数,请将其称为:

foo(1, 2) # => "{}"
Run Code Online (Sandbox Code Playgroud)

如果你有可选的东西,你可以这样称呼它:

foo(1, 2, {truncate: true, redirect_to: '/'}) # => "{:truncate=>true, :redirect_to=>\"/\"}"
Run Code Online (Sandbox Code Playgroud)

这个代码对于ruby来说是非常惯用的,它的解析器实际上允许你在将hash作为方法的最后一个参数传递时省略花括号:

foo(1, 2, truncate: true, redirect_to: '/') # => "{:truncate=>true, :redirect_to=>\"/\"}"
Run Code Online (Sandbox Code Playgroud)

例如,如果你使用rails,你会看到各处的选项哈希值.在这里,我在我的应用程序中打开了一个随机控制器:

class ProductsController < ApplicationController
  before_filter :prepare_search_params, only: :index
                                    #    ^^^^^^^^^^ options hash here
Run Code Online (Sandbox Code Playgroud)

所以,简而言之:options hash是一个方法的参数,它位于最后,默认值为{}.你通常会把哈希传给它(因此得名).

  • 在现代版本的Ruby上,您应该使用关键字参数而不是选项哈希. (7认同)

dim*_*ope 9

当需要将可选参数传递给方法时,会大量使用选项哈希.

例如,如果method有两个可选的args,你可以编写

def method(arg1, arg2 = nil, arg3 = nil)
  ...
end
Run Code Online (Sandbox Code Playgroud)

但是如果你有更多可选的arg,那么每次将它们分配给nil都会变得很难看.这里有选项哈希,允许你写

def method(arg1, options={})
  @arg1 = arg1
  @arg2 = options[:arg2]
  ....
  @arg15 = options[:arg15]
end
Run Code Online (Sandbox Code Playgroud)


Max*_*Max 6

选项哈希是指使用hash({})将选项传递给方法的约定

my_func(arg1, arg2, {:opt1 => 'foo', :opt2 => 'bar'})
Run Code Online (Sandbox Code Playgroud)

惯例是将选项哈希作为最后一个参数,以便可以将其设置为可选.例如

def my_func(argument1, argument2, options = {})
   ...
end
Run Code Online (Sandbox Code Playgroud)

所以选项哈希并不特别.它只是一个可选的最后一个参数,它是一个哈希.选项哈希非常方便和通用,翻译也可以让你不用括号(这是关于它们的"特殊"部分)

my_func(arg1, arg2, :opt1 => 'foo', :opt2 => 'bar')
Run Code Online (Sandbox Code Playgroud)

结合Ruby的Symbol哈希键快捷键和可选括号,这可以看起来非常干净:

my_func arg1, arg2, opt1: 'foo', opt2: 'bar'
Run Code Online (Sandbox Code Playgroud)


Ale*_*bio 5

由于所有这些答案都是正确的,因此ruby 2改进了对关键字参数的支持。

您可以使用默认的哈希参数as定义方法*args,然后删除options = {}

def foo(bar: 'initial')
  puts bar
end

foo # => 'initial'
foo(bar: 'final') # => 'final'
Run Code Online (Sandbox Code Playgroud)

必需参数:密钥后需要冒号(也需要ruby 2.1)

def foo(bar:)
  puts bar
end

foo # => ArgumentError: missing keyword: bar
foo(bar: 'baz') # => 'baz'   
Run Code Online (Sandbox Code Playgroud)

可选参数,您可以将默认设置为 nil

def foo(bar: nil, baz: 'aaa')
  puts "#{bar}:#{baz}"
end

foo # => ':aaa'
foo(baz: 'zab') # => ':zab'
foo(bar: 'rab', baz: 'zab') # => 'rab:zab'
foo(bin: 'bin') # => ArgumentError: unknown keyword: bin
Run Code Online (Sandbox Code Playgroud)

您也可以将标准位置args与该新的哈希参数符号一起使用。您可以在此博客官方文档中找到更多信息。

奖励:重构很容易,因为您可以摆脱方法的options哈希,而无需更改其调用。但是...这并非完全正确,如果您拨打带有意外选项的电话,则会收到ArgumentError: unknown keyword: invalid_arg