7
votes

Utiliser un lambda par défaut dans Hash # fetch ruby

Je lisais Ruby confiant et j'essayais de définir un processus réutilisable. À partir des exemples donnés, j'ai écrit ceci:

DEFAULT_BLOCK = -> { 'block executed' }

answers = {}

answers.fetch(:x, &DEFAULT_BLOCK)

Je m'attendais à ce qu'il retourne bloc exécuté car x n'est pas trouvé dans le hachage mais à la place, il a renvoyé un nombre incorrect d'arguments (donné 1, attendu 0) (ArgumentError) . Quel pourrait être le problème? Je n'ai pas donné d'argument au bloc.


0 commentaires

3 Réponses :


3
votes

Lorsque Hash # fetch prend un bloc, la clé est passée au bloc. Mais votre bloc créé à partir d'un proc ne prend aucun argument de bloc. Remplacez la définition par:

DEFAULT_BLOCK = -> x { 'block executed' }


0 commentaires

9
votes

Vous avez, vous ne le voyez tout simplement pas:

DEFAULT_BLOCK = proc { 'block executed' }
answers.fetch(:x, &DEFAULT_BLOCK)
# => "block executed" 

Le bloc de Hash # fetch fournit un argument, la clé que vous n'avez pas trouvée . Vous pouvez soit accepter un argument dans votre lambda et simplement l'ignorer, soit en faire un proc:

WHAT_AM_I_PASSING = ->(var) { var.inspect }

answers = {}

answers.fetch(:x, &WHAT_AM_I_PASSING)
# => ":x"

La raison pour laquelle un proc fonctionne, c'est que lambdas vérifie que le nombre correct des arguments ont été fournis tandis que procs ne le font pas. La méthode fetch appelle le proc / lambda avec un argument (la clé).


0 commentaires

0
votes
    2.6.1 :014 > DEFAULT_BLOCK = -> { 'block executed' }
     => #<Proc:0x00005586f6ef9e58@(irb):14 (lambda)> 
    2.6.1 :015 > answers = {}
     => {} 
    2.6.1 :016 > ans = answers.fetch(:x) {DEFAULT_BLOCK}
     => #<Proc:0x00005586f6ef9e58@(irb):14 (lambda)> 
    2.6.1 :017 > ans.call
     => "block executed" 

    Actually we can pass default value for key so that if key not found in the hash it use this default value like,
    my_hash = {}
     => {} 
    2.6.1 :019 > my_hash[:key1] = 'val1'
     => "val1" 
    2.6.1 :020 > p my_hash
    {:key1=>"val1"}
     => {:key1=>"val1"} 
    2.6.1 :022 > my_hash.fetch(:key1)
     => "val1" 
    2.6.1 :023 > my_hash.fetch(:key2)
    KeyError (key not found: :key2)
    Did you mean?  :key1
    2.6.1 :024 > my_hash.fetch(:key2){'val2'}
     => "val2" 

1 commentaires

Je l'ai utilisé dans irb de ruby ​​version 2.6.1