2013-08-23 38 views

回答

44

选项哈希是一个不错的概念,由Ruby解析器的功能启用。比方说,你有一个有一些必要参数的方法。你也可以传递一些可选参数。随着时间的推移,您可以添加更多可选参数或删除旧参数。为了使方法声明保持干净和稳定,可以将所有这些可选参数传递给哈希。这种方法是这样的:

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

所以它有两个必需的值,并与哈希的默认值最后一个参数。如果你没有任何可选的参数传递,你怎么称呼它是这样的:

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

如果你确实有一些可选的,你们说是这样的:

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

此代码是如此习惯红宝石,它实际上解析器允许你通过哈希时,作为最后一个参数的方法省略花括号:

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

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

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

因此,简而言之:哈希选项是位于最后并具有{}默认值的方法的参数。你通常会把哈希传给它(因此名字)。

+7

在现代版本的Ruby中,您应该真正使用关键字参数而不是选项哈希。 –

+0

@JörgWMittag你能解释一下吗? – Dennis

+1

@ Dennis:google“ruby关键字参数” –

5

一个选项散列是指通过选项,根据惯例来使用散列({})像这样

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

的约定是用于选择散列是最后一个参数的方法,以便它可以由任选的。例如。

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

所以选项散列没有什么特别的。这只是一个可选的最终参数,它是一个散列。选项哈希值是那么得心应手,共同的解释也让你离开花括号(这是一个关于他们的“特殊”的一部分)

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

与Ruby的符号散快捷键和可选圆括号相结合,这可以结束寻找真正的清洁:

my_func arg1, arg2, opt1: 'foo', opt2: 'bar' 
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 
9

选项哈希值,当n采用了大量eed将可选参数传递给方法。

例如,如果方法有一个,两个可选的指定参数时,你可以写

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

但如果你有多个可选的ARG它变得丑陋将其分配到零每次。 这里谈到的选项哈希,让你写

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

由于所有这些问题的答案是正确的,红宝石2提高到关键字参数的支持。

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

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

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

必需的参数:你需要一个冒号键后(还需要红宝石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