将参数传递给Ruby中的传入块

时间:2013-10-14 12:38:06

标签: ruby

我想将一个块传递给一个函数,然后用一些附加参数调用该块,如下所示:

def foo(&block)
  some_array = (1..3).to_a
  x = 7 # Simplified
  result = some_array.map &block # Need some way to pass in 'x' here
end

def a_usage_that_works
  foo do |value|
    value
  end
end

def a_usage_that_doesnt_work
  foo do |value, x|
    x # How do I pass in x?
  end
end

# rspec to demonstrate problem / required result
describe "spike" do
  it "works" do
    a_usage_that_works.should == [1,2,3]
  end
  it "doesn't work" do
    a_usage_that_doesnt_work.should == [7, 7, 7]
  end
end

如何将附加参数传递给块?

3 个答案:

答案 0 :(得分:2)

创建另一个块并从中调用第一个块。

def foo(&block)
  some_array = (1..3).to_a
  x = 7 # Simplified
  result = some_array.map {|elem| block.call(elem, x)}
end

答案 1 :(得分:1)

你通过屈服于它来传递给该区块。

def foo(&block)
  some_array = [1,2,3]
  x = 7
  some_array.map{|el| yield el, x}
end

p foo{|p1, p2| p2} #=>[7,7,7]
p foo{|p1, p2| p1} #=>[1,2,3]

答案 2 :(得分:0)

您可以使用higher-order function生成简化函数:

我们假设我们传递给foo的块将接受value, x

朴素策略,使用内联定义的x

def foo(&block)
  some_array = (1..3).to_a
  x = 7
  simple_func = proc {|value| block.call(value, x) }
  result = some_array.map &simple_func
end

使用关注点分离的策略:

def get_simple_func(block)
  # This assumes x won't change per iteration.
  # If it can change, you can move the calculation inside the proc.
  # Moving it inside also allows the calculation to depend on "value", in case you want that.
  x = complex_calculation_for_x()
  proc {|value| block.call(value, x) }
end

def foo(&block)
  some_array = (1..3).to_a
  simple_func = get_simple_func(block)
  result = some_array.map &simple_func
end

显然,当x是一个字面值时,你不应该使用它,因为它会过度工程化。但随着x的计算变得更加复杂,将其分离会使代码更具可读性。此外,foo可以专注于将功能应用于some_array的具体任务。