什么是期权哈希?

时间:2013-08-23 16:26:47

标签: ruby options hash

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

5 个答案:

答案 0 :(得分:48)

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

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

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

foo(1, 2) # => "{}"

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

foo(1, 2, {truncate: true, redirect_to: '/'}) # => "{:truncate=>true, :redirect_to=>\"/\"}"

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

foo(1, 2, truncate: true, redirect_to: '/') # => "{:truncate=>true, :redirect_to=>\"/\"}"

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

class ProductsController < ApplicationController
  before_filter :prepare_search_params, only: :index
                                    #    ^^^^^^^^^^ options hash here

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

答案 1 :(得分:9)

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

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

def method(arg1, arg2 = nil, arg3 = nil)
  ...
end

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

def method(arg1, options={})
  @arg1 = arg1
  @arg2 = options[:arg2]
  ....
  @arg15 = options[:arg15]
end

答案 2 :(得分:6)

选项哈希指的是使用散列({})将选项传递给方法的惯例

my_func(arg1, arg2, {:opt1 => 'foo', :opt2 => 'bar'})

约定是将选项哈希作为最后一个参数,以便可以使其成为可选项。 E.g。

def my_func(argument1, argument2, options = {})
   ...
end

所以选项哈希并不是什么特别的东西。它只是一个可选的最后一个参数,它是一个哈希。选项哈希是如此方便和常见,以至于口译员也可以让你不用括号(这是关于他们的“特殊”部分)

my_func(arg1, arg2, :opt1 => 'foo', :opt2 => 'bar')

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

my_func arg1, arg2, opt1: 'foo', opt2: 'bar'

答案 3 :(得分:5)

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

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

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

foo # => 'initial'
foo(bar: 'final') # => 'final'

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

def foo(bar:)
  puts bar
end

foo # => ArgumentError: missing keyword: bar
foo(bar: 'baz') # => 'baz'   

可选参数,您可以将默认值设置为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

此外,您可以使用带有此新哈希参数表示法的标准位置参数。您可以在blogoficial文档中找到更多信息。

奖励:重构很简单,因为您可以在不更改调用的情况下删除方法的选项哈希值。但是......这并不完全正确,如果你有一个带有意外选项的电话,你将获得ArgumentError: unknown keyword: invalid_arg

答案 4 :(得分:2)

反向合并是在ruby / rails中实现选项哈希的最佳方法:

def set_state_application(options_hash)
  options_hash.reverse_merge!(send_email: true, other_default_val: 'a') #will set defaults
  self.update_column(:status_id, VendorEnums::VendorStatus::APPLICATION)
  VendorMailer.email_application(self) if options_hash[:send_email]
  save_state
end