web-dev-qa-db-ja.com

オプションハッシュとは何ですか?

誰かがオプションハッシュを説明してくれますか?私はtestfirst.orgのRubyコースを使用しています。演習10(temperature_object)にはオプションハッシュの知識が必要です。

29
colewest

オプションハッシュは、Rubyパーサーの機能によって有効にされるニースの概念です。たとえば、いくつかの必須の引数を持つメソッドがあります。また、いくつかのオプションの引数を渡すことができます。メソッド宣言をクリーンで安定した状態に保つために、これらのオプションの引数をすべてハッシュで渡すことができます。このようなメソッドは次のようになります。

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

そのため、2つの必須値とハッシュのデフォルト値を持つ最後の引数があります。渡すオプションの引数がない場合は、次のように呼び出します。

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

オプションがある場合は、次のように呼び出します。

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

このコードはRubyにイディオムであるため、メソッドの最後の引数としてハッシュを渡すときに、そのパーサーは実際に中括弧を省略できます。

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

たとえば、Railsを使用する場合、オプションハッシュeverywhereが表示されます。ここでは、アプリでランダムコントローラーのみを開きました。

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

つまり、要するに:options hashは最後に位置し、{}のデフォルト値を持つメソッドの引数です。そして、通常はハッシュを渡します(そのため名前です)。

49

オプションのハッシュは、オプションの引数をメソッドに渡す必要がある場合によく使用されます。

たとえば、メソッドに1〜2個のオプションの引数がある場合、次のように記述できます。

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

しかし、オプションの引数がもっとある場合、毎回それらをnilに割り当てるのは面倒です。ここにあなたが書くことを可能にするオプションハッシュがあります

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

オプションハッシュは、ハッシュ({}) そのようです

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'
6
Max

これらの答えはすべて正しいため、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

また、この新しいハッシュパラメータ表記法で標準の位置引数を使用できます。詳細については、この blog および oficial のドキュメントを参照してください。

ボーナス:メソッドの呼び出しを変更せずにメソッドのオプションハッシュを削除できるため、リファクタリングは簡単です。しかし......これは完全に真実ではありません。予期しないオプションで呼び出しがあった場合、ArgumentError: unknown keyword: invalid_argが返されます。

5
Alejandro Babio

逆マージは、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
3