如何将lambda传递给Hash.each?

Dra*_*Fax 5 ruby lambda

我怎样才能传递一个lambda hash.each,所以我可以重用一些代码?

> h = { a: 'b' }
> h.each do |key, value| end
 => {:a=>"b"}
> test = lambda do |key, value| puts "#{key} = #{value}" end 
> test.call('a','b')
a = b
> h.each &test
ArgumentError: wrong number of arguments (1 for 2)
  from (irb):1:in `block in irb_binding'
  from (irb):5:in `each'
  from (irb):5
  from /Users/jstillwell/.rvm/rubies/ruby-1.9.3-p362/bin/irb:16:in `<main>'
> h.each test
ArgumentError: wrong number of arguments(1 for 0)
  from (irb):8:in `each'
  from (irb):8
  from /Users/jstillwell/.rvm/rubies/ruby-1.9.3-p362/bin/irb:16:in `<main>'
Run Code Online (Sandbox Code Playgroud)

Jör*_*tag 11

each产生当前元素到块,ergo lambda需要一个参数,而不是两个.在Hash产生元素的情况下是两元素Array,其中第一元素是键,第二元素是值.

test = lambda do |el| puts "#{el.first} = #{el.last}" end
h.each &test
# a = b
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用Ruby的支持在参数列表中解构bind:

test = lambda do |(k, v)| puts "#{k} = #{v}" end
h.each &test
# a = b
Run Code Online (Sandbox Code Playgroud)

或者,不是使用lambda具有相同参数绑定语义的方法,而是使用a Proc,它具有与块相同的参数绑定语义,即它将单个Array参数解包为多个参数绑定:

test = proc do |k, v| puts "#{k} = #{v}" end
h.each &test
# a = b
Run Code Online (Sandbox Code Playgroud)

  • 是的,并且`Proc`具有相同的参数传递语义作为块(宽松的arity检查,数组解包),而`lambda`s具有相同的参数传递语义作为方法(严格的arity检查,没有解包). (2认同)