ruby 什么是选项哈希?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18407618/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are options hashes?
提问by colewest
Will someone please explain options hashes? I am working through the ruby course from testfirst.org. Exercise 10 (temperature_object) requires knowledge of options hashes.
有人会解释选项哈希吗?我正在学习 testfirst.org 的 ruby 课程。练习 10 (temperature_object) 需要选项哈希的知识。
回答by Sergio Tulentsev
Options hash is a nice concept enabled by a feature of ruby parser. Say, you have a method with some required arguments. Also you may pass some optional arguments. Over time you may add more optional arguments or remove old ones. To keep method declaration clean and stable, you can pass all those optional arguments in a hash. Such method would look like this:
选项哈希是一个很好的概念,由 ruby 解析器的一个特性启用。假设您有一个带有一些必需参数的方法。您也可以传递一些可选参数。随着时间的推移,您可能会添加更多可选参数或删除旧参数。为了保持方法声明的干净和稳定,您可以在散列中传递所有这些可选参数。这种方法看起来像这样:
def foo(arg1, arg2, opts = {})
opts.to_s # just return a string value of opts
end
So it has two required values and last argument with default value of hash. If you don't have any optional arguments to pass, you call it like this:
所以它有两个必需的值和最后一个参数,默认值为哈希。如果您没有任何可选参数要传递,您可以这样调用它:
foo(1, 2) # => "{}"
If you do have something optional, you call it like this:
如果你确实有一些可选的东西,你可以这样称呼它:
foo(1, 2, {truncate: true, redirect_to: '/'}) # => "{:truncate=>true, :redirect_to=>\"/\"}"
This code is so idiomatic to ruby that its parser actually allows you to omit curly braces when passing hash as a last argument to a method:
这段代码非常符合 ruby 的习惯,以至于它的解析器实际上允许您在将哈希作为方法的最后一个参数传递时省略花括号:
foo(1, 2, truncate: true, redirect_to: '/') # => "{:truncate=>true, :redirect_to=>\"/\"}"
If you use rails, for example, you'll see options hashes everywhere. Here, I opened just a random controller in my app:
例如,如果您使用 rails,您会在任何地方看到 options hashes 。在这里,我在我的应用程序中只打开了一个随机控制器:
class ProductsController < ApplicationController
before_filter :prepare_search_params, only: :index
# ^^^^^^^^^^ options hash here
So, in short: options hash is argument of a method which is located last and has default value of {}. And you normally pass hashes to it (hence the name).
因此,简而言之:options hash 是最后一个方法的参数,默认值为{}。您通常将哈希值传递给它(因此得名)。
回答by dimitryeurope
Options hashes are used a lot when need to pass optional arguments to method.
当需要将可选参数传递给方法时,会经常使用选项哈希。
For example, if method has one-two optional args, you can write
例如,如果方法具有一两个可选参数,则可以编写
def method(arg1, arg2 = nil, arg3 = nil)
...
end
But if you have more optional arg it's getting ugly to assign them to nil every time. Here comes the options hash which allows you to write
但是如果你有更多的可选参数,每次都将它们分配给 nil 会变得很难看。这是选项哈希,它允许您编写
def method(arg1, options={})
@arg1 = arg1
@arg2 = options[:arg2]
....
@arg15 = options[:arg15]
end
回答by Max
An options hash refers to the convention of passing options to methods using a hash ({}) like so
选项散列是指使用散列 ( {})将选项传递给方法的约定,如下所示
my_func(arg1, arg2, {:opt1 => 'foo', :opt2 => 'bar'})
The convention is for the options hash to be the last argument so that it can be made optional. E.g.
约定是选项散列是最后一个参数,以便它可以成为可选的。例如
def my_func(argument1, argument2, options = {})
...
end
So an options hash isn't anything special. It's just an optional final argument that is a hash. Options hashes are so handy and common that the interpreter also lets you leave off the braces (this is the one "special" part about them)
所以选项哈希并不是什么特别的。它只是一个可选的最终参数,它是一个哈希值。选项哈希是如此方便和常见,以至于解释器还让您不用大括号(这是关于它们的一个“特殊”部分)
my_func(arg1, arg2, :opt1 => 'foo', :opt2 => 'bar')
Combined with Ruby's Symbol hash key shortcut and optional parentheses, this can end looking really clean:
结合 Ruby 的 Symbol 哈希键快捷键和可选括号,这看起来非常干净:
my_func arg1, arg2, opt1: 'foo', opt2: 'bar'
回答by Alejandro Babio
Since all these answers are correct, ruby 2 improved the support to keywords arguments.
由于所有这些答案都是正确的,ruby 2 改进了对关键字参数的支持。
You can define your method with the default hash params as *args, and rid the options = {}.
您可以使用默认哈希参数定义您的方法*args,并删除options = {}.
def foo(bar: 'initial')
puts bar
end
foo # => 'initial'
foo(bar: 'final') # => 'final'
Required arguments: you need a colon after the key (also you need ruby 2.1)
必需参数:键后需要一个冒号(还需要 ruby 2.1)
def foo(bar:)
puts bar
end
foo # => ArgumentError: missing keyword: bar
foo(bar: 'baz') # => 'baz'
Optional arguments, you can set the default to nil
可选参数,您可以将默认值设置为 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
Also you can use the standard positional args with this new hash parameters notation. You will find more information at this blogand at the oficialdocumentation.
您也可以使用带有这个新散列参数符号的标准位置参数。您可以在此博客和官方文档中找到更多信息。
Bonus: The refactor is easy because you can rid the options hash of your method without change the calls of it. But... this is not completely true, if you have a call with an unexpected option you will get an ArgumentError: unknown keyword: invalid_arg.
奖励:重构很容易,因为您可以在不更改方法调用的情况下删除方法的选项哈希。但是...这并不完全正确,如果您有一个带有意外选项的呼叫,您将得到一个ArgumentError: unknown keyword: invalid_arg.
回答by Carlos Cervantes
Reverse Merge is the best way to implement options hashes in ruby/rails:
反向合并是在 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

