web-dev-qa-db-fra.com

Que sont les hachages d'options?

Quelqu'un pourrait-il expliquer les hachages d'options? Je suis en train de suivre le cours Ruby de testfirst.org. L'exercice 10 (temperature_object) nécessite la connaissance des options de hachage.

29
colewest

Le hachage des options est un concept agréable activé par une fonctionnalité de Ruby. Disons que vous avez une méthode avec certains arguments requis. Vous pouvez également passer des arguments facultatifs. Au fil du temps, vous pouvez ajouter d'autres arguments facultatifs ou supprimez les anciens. Pour garder la déclaration de méthode propre et stable, vous pouvez passer tous ces arguments facultatifs dans un hachage. Cette méthode ressemblerait à ceci:

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

Il a donc deux valeurs requises et le dernier argument avec la valeur par défaut de hachage. Si vous n'avez aucun argument facultatif à passer, vous l'appelez comme ceci:

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

Si vous avez quelque chose de facultatif, vous l'appelez comme ceci:

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

Ce code est tellement idiomatique pour Ruby que son analyseur vous permet en fait d'omettre les accolades lorsque vous passez le hachage comme dernier argument à une méthode:

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

Si vous utilisez Rails, par exemple, vous verrez des hachages d'options partout . Ici, j'ai ouvert juste un contrôleur aléatoire dans mon application:

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

Donc, en bref: le hachage des options est l'argument d'une méthode qui se trouve en dernier et a la valeur par défaut de {}. Et vous lui passez normalement des hachages (d'où le nom).

49
Sergio Tulentsev

Les hachages d'options sont beaucoup utilisés lorsque vous avez besoin de passer des arguments facultatifs à la méthode.

Par exemple, si la méthode a un ou deux arguments facultatifs, vous pouvez écrire

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

Mais si vous avez plus d'arguments optionnels, il devient moche de les affecter à zéro à chaque fois. Voici le hachage d'options qui vous permet d'écrire

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

Un hachage d'options fait référence à la convention de passage d'options à des méthodes utilisant un hachage ({}) ainsi

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

La convention veut que le hachage des options soit le dernier argument afin qu'il puisse être rendu facultatif. Par exemple.

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

Un hachage d'options n'a donc rien de spécial. C'est juste un argument final facultatif qui est un hachage. Les hachages d'options sont si pratiques et communs que l'interprète vous permet également de laisser les accolades (c'est la seule partie "spéciale" à leur sujet)

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

Combiné avec le raccourci clavier de hachage du symbole de Ruby et les parenthèses facultatives, cela peut finir par sembler très propre:

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

Étant donné que toutes ces réponses sont correctes, Ruby 2 a amélioré la prise en charge des arguments de mots clés.

Vous pouvez définir votre méthode avec les paramètres de hachage par défaut comme *args, et débarrasser le options = {}.

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

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

Arguments requis: vous avez besoin de deux points après la clé (vous avez également besoin de Ruby 2.1)

def foo(bar:)
  puts bar
end

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

Arguments facultatifs, vous pouvez définir la valeur par défaut sur 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

Vous pouvez également utiliser les arguments positionnels standard avec cette nouvelle notation des paramètres de hachage. Vous trouverez plus d'informations dans cette blog et dans la documentation oficial .

Bonus: Le refactor est facile car vous pouvez supprimer le hachage des options de votre méthode sans en changer les appels. Mais ... ce n'est pas tout à fait vrai, si vous avez un appel avec une option inattendue, vous obtiendrez un ArgumentError: unknown keyword: invalid_arg.

5
Alejandro Babio

La fusion inversée est le meilleur moyen d'implémenter des hachages d'options dans 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
Carlos Cervantes