Search code examples
rubyruby-hash

Using a lambda as a default in Hash#fetch ruby


I was reading through confident ruby and I was trying out how to define a reusable proc. From the examples given, I wrote this:

DEFAULT_BLOCK = -> { 'block executed' }

answers = {}

answers.fetch(:x, &DEFAULT_BLOCK)

I was expecting it to return block executed since x is not found in the Hash but instead it returned wrong number of arguments (given 1, expected 0) (ArgumentError). What could the problem be? I haven't given the block an argument.


Solution

  • You have, you just don't see it:

    WHAT_AM_I_PASSING = ->(var) { var.inspect }
    
    answers = {}
    
    answers.fetch(:x, &WHAT_AM_I_PASSING)
    # => ":x"
    

    The block of Hash#fetch provides an argument, the key that you haven't found. You can either accept an argument in your lambda and just ignore it, or make it a proc:

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

    The reason that a proc works, is that lambdas verify that the correct number of arguments were provided while procs don't. The fetch method is calling the proc/lambda with one argument (the key).