web-dev-qa-db-fra.com

Comment les méthodes utilisent-elles les arguments de hachage dans Ruby?

J'ai vu des arguments de hachage utilisés dans certaines méthodes de bibliothèque pendant que j'apprenais.

Par exemple.,

list.search(:titles, genre: 'jazz', duration_less_than: 270)

Quelqu'un peut-il expliquer comment une méthode utilise des arguments comme celui-ci et comment vous pouvez créer une méthode qui utilise des arguments de hachage?

34
Senjai

Exemple:

def foo(regular, hash={})
    puts "regular: #{regular}"
    puts "hash: #{hash}"
    puts "a: #{hash[:a]}"
    puts "b: #{hash[:b]}"
end

foo("regular argument", a: 12, :b => 13)

J'utilise hash={} pour spécifier que le dernier argument est un hachage, avec la valeur par défaut de hachage vide. Maintenant, quand j'écris:

foo("regular argument", a: 12, :b => 13)

C'est en fait un sucre syntaxique pour:

foo("regular argument", {a: 12, :b => 13})

Également, {a: 12} est du sucre syntaxique pour {:a => 12}.

Lorsque tout cela est combiné, vous obtenez une syntaxe qui ressemble aux arguments nommés dans d'autres langues.

53
Idan Arye

Dans Ruby 2.x, vous pouvez utiliser ** splat de hachage:

def foo( ordered_argument, **named_arguments )
  puts "Ordered argument: #{ordered_argument}"
  puts "Named arguments: #{named_arguments}"
end

foo( :titles, genre: 'jazz', duration_less_than: 270 )
#=> Ordered argument: titles
#=> Named arguments: {:genre=>"jazz", :duration_less_than=>270}
28
Boris Stitnicky

Lorsqu'une Ruby se termine par une ou plusieurs paires clé-valeur, comme foo: 'bar' ou 'foo' => 1, Ruby les collecte tous dans un seul hachage et passe ce hachage comme dernier paramètre. Vous pouvez le voir vous-même dans irb:

irb(main):002:0> puts foo: 'bar', baz: 'quux'
{:foo=>"bar", :baz=>"quux"}
=> nil

Ainsi, vous pouvez ajouter un dernier paramètre facultatif à une méthode que vous écrivez pour recevoir ce hachage. Vous voudrez généralement le définir par défaut sur un hachage vide. Vous pouvez appeler le paramètre comme vous le souhaitez, mais options est un nom courant:

def my_method(a, b, c, options = {})
  ...
end

Une astuce utile si vous utilisez Rails: il est souvent pratique de traiter les chaînes et les symboles simples comme équivalents. Rails ajoute un symbolize_keys! méthode en Hash pour convertir toutes les clés de chaîne en symboles:

def my_method(a, b, c, options = {})
  options.symbolize_keys!
  ...
end
11

Je ferais l'une des deux options:

1- Si a obtenu un grand nombre d'arguments à passer dans une méthode, j'utiliserais un hachage comme ceci:

some_method({titles => 'titulo', genre => 'jazz', duration_less_than => 270})

ou

my_hash = {titles => 'titulo', genre => 'jazz', duration_less_than => 270}
some_method(my_hash)

et

def some_method(hash_options)
  #important code
end

2- L'option sera plus "traditionnelle"

some_method('titulo', 'jazz', 270)

def some_method(titles, genre, duration_less_than)
#important code
end
3
M.Octavio

Depuis Ruby 2.0 vous pouvez utiliser des arguments de mots clés [1] [2] par opposition au seul paramètre Hash.

def foo(keyword_arg: 'bar')
  keyword_arg
end

Et voici comment cela se comporte.

> foo
=> "bar"
> foo(keyword_arg: 'baz')
=> "baz"
  1. http://robots.thoughtbot.com/Ruby-2-keyword-arguments
  2. http://brainspec.com/blog/2012/10/08/keyword-arguments-Ruby-2-0/
3
Dennis

Voici comment je le fais:

def my_method(title, args)
  puts title
  puts args

passage des paramètres:

my_method('test title', a: 'foo', b: 'bar')
  # => test title
  # => '{:a => 'foo', :b => 'bar'}
2
tokhi