wake-up-neo.net

Was sind Options-Hashes?

Erklärt jemand bitte Optionen Hashes? Ich arbeite mich durch den Ruby Kurs von testfirst.org. Übung 10 (temperature_object) erfordert Kenntnisse über Options-Hashes.

29
colewest

Options-Hash ist ein Nizza-Konzept, das durch eine Funktion des Ruby Parsers aktiviert wird. Angenommen, Sie haben eine Methode mit einigen erforderlichen Argumenten. Außerdem können Sie einige optionale Argumente übergeben. Mit der Zeit können Sie weitere optionale Argumente hinzufügen Um die Methodendeklaration sauber und stabil zu halten, können Sie alle diese optionalen Argumente in einem Hash übergeben.

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

Es hat also zwei erforderliche Werte und das letzte Argument mit dem Standardwert von Hash. Wenn Sie keine optionalen Argumente übergeben müssen, nennen Sie es wie folgt:

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

Wenn Sie etwas optionales haben, nennen Sie es wie folgt:

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

Dieser Code ist für Ruby) so idiomatisch, dass Sie mit seinem Parser geschweifte Klammern weglassen können, wenn Sie Hash als letztes Argument an eine Methode übergeben:

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

Wenn Sie beispielsweise Rails verwenden, werden überall Options-Hashes angezeigt . Hier habe ich nur einen zufälligen Controller in meiner App geöffnet:

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

Also, kurz gesagt: options hash ist das Argument einer Methode, die sich zuletzt befindet und den Standardwert {} Hat. Und normalerweise übergeben Sie Hashes (daher der Name).

49

Options-Hashes werden häufig verwendet, wenn optionale Argumente an method übergeben werden müssen.

Wenn die Methode beispielsweise zwei optionale Argumente enthält, können Sie schreiben

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

Aber wenn Sie mehr optionale Argumente haben, wird es hässlich, sie jedes Mal null zuzuweisen. Hier kommt der Options-Hash, mit dem Sie schreiben können

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

Ein Options-Hash bezieht sich auf die Konvention, Optionen mit einem Hash ({}) gefällt mir

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

Die Konvention sieht vor, dass der Options-Hash das letzte Argument ist, damit er optional angegeben werden kann. Z.B.

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

Ein Options-Hash ist also nichts Besonderes. Es ist nur ein optionales abschließendes Argument, das ein Hash ist. Options-Hashes sind so praktisch und gebräuchlich, dass Sie mit dem Interpreter auch die geschweiften Klammern weglassen können (dies ist der eine "besondere" Teil an ihnen).

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

In Kombination mit Rubys Symbol-Hash-Tastenkürzel und optionalen Klammern kann dies dazu führen, dass das Ergebnis sehr sauber aussieht:

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

Da alle diese Antworten korrekt sind, hat Ruby 2 die Unterstützung für Schlüsselwortargumente verbessert.

Sie können Ihre Methode mit den Standard-Hash-Parametern *args Definieren und options = {} Entfernen.

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

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

Erforderliche Argumente: Sie brauchen einen Doppelpunkt nach dem Schlüssel (auch Sie brauchen Ruby 2.1)

def foo(bar:)
  puts bar
end

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

Optionale Argumente, Sie können den Standardwert auf nil setzen

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

Sie können auch die Standard-Positionsargumente mit dieser neuen Hash-Parameter-Notation verwenden. Weitere Informationen finden Sie in dieser Blog und in der offiziellen Dokumentation.

Bonus: Der Refactor ist einfach, da Sie den Options-Hash Ihrer Methode entziehen können, ohne die Aufrufe davon zu ändern. Aber ... das ist nicht ganz richtig. Wenn Sie einen Anruf mit einer unerwarteten Option haben, erhalten Sie einen ArgumentError: unknown keyword: invalid_arg.

5
Alejandro Babio

Reverse Merge ist die beste Möglichkeit, Options-Hashes in Ruby/Rails zu implementieren:

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