7

我正在阅读自信的 ruby​​,并且正在尝试如何定义可重用的 proc。从给出的例子中,我写了这个:

DEFAULT_BLOCK = -> { 'block executed' }

answers = {}

answers.fetch(:x, &DEFAULT_BLOCK)

我期待它返回block executed,因为x在 Hash 中找不到它,而是返回了wrong number of arguments (given 1, expected 0) (ArgumentError)。问题可能是什么?我没有给这个块一个论点。

4

3 回答 3

9

你有,你只是没有看到它:

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

answers = {}

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

Hash#fetch提供了一个参数,即您尚未找到的键。您可以接受 lambda 中的参数并忽略它,或者将其设为 proc:

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

proc 起作用的原因是 lambdas 验证提供了正确数量的参数,而 procs 没有。该fetch方法使用一个参数(键)调用 proc/lambda。

于 2019-02-06T09:04:33.033 回答
3

获取块时Hash#fetch,将密钥传递给块。但是您从 proc 创建的块不采用任何块参数。将定义更改为:

DEFAULT_BLOCK = -> x { 'block executed' }
于 2019-02-06T09:01:29.907 回答
0
    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" 
于 2019-02-06T10:29:51.827 回答