有人会解释选项哈希吗?我正在学习 testfirst.org 的 ruby 课程。练习 10 (temperature_object) 需要了解选项哈希。
5 回答
选项哈希是一个很好的概念,由 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=>\"/\"}"
这段代码对 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 是位于最后且具有默认值的方法的参数{}
。您通常会将哈希传递给它(因此得名)。
当需要将可选参数传递给方法时,会经常使用选项哈希。
例如,如果方法有一两个可选参数,你可以写
def method(arg1, arg2 = nil, arg3 = nil)
...
end
但是,如果您有更多可选参数,那么每次都将它们分配为 nil 会变得很难看。这是允许您编写的选项哈希
def method(arg1, options={})
@arg1 = arg1
@arg2 = options[:arg2]
....
@arg15 = options[:arg15]
end
{}
选项散列是指使用散列 ( )将选项传递给方法的约定,如下所示
my_func(arg1, arg2, {:opt1 => 'foo', :opt2 => 'bar'})
约定是将选项散列作为最后一个参数,以便可以将其设为可选。例如
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'
由于所有这些答案都是正确的,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
您也可以将标准位置参数与这个新的散列参数表示法一起使用。您将在此博客和官方文档中找到更多信息。
奖励:重构很容易,因为您可以在不更改方法调用的情况下摆脱方法的选项哈希。但是......这并不完全正确,如果您有一个带有意外选项的电话,您将获得一个ArgumentError: unknown keyword: invalid_arg
.
反向合并是在 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