2

我正在尝试弄清楚如何将语句作为方法参数传递 - 用作块过滤条件的一部分。例如,我有以下代码:

def method
  other_method.persons.each do |ped|

    next if ped.first_name.nil? or ped.last_name.nil?

    puts ped.id
    puts ped.full_name
  end
end

我希望能够做的如下(因此我可以更改方法中使用的过滤条件)。是否可以将包含块引用的语句从参数传递给块?:

def method(statement)
  other_method.persons.each do |ped|

    next if statement

    puts ped.id
    puts ped.full_name
  end
end

我很欣赏这方面的一些方向。

4

2 回答 2

6

您不通过“声明”,而是通过了块。传递的块通过调用yield或捕获到 proc 中并使用 调用Proc#call

def method
  other_method.persons.each do |ped|
    next if yield(ped)

    puts ped.id
    puts ped.full_name
  end
end

method { |ped| ped.first_name.nil? or ped.last_name.nil? }
于 2012-11-16T18:08:40.953 回答
0
Ped = Struct.new(:first_name, :last_name, :full_name, :id)

# generate some test data
peds = ['Bob', 'Hope', 'Bob Hope', 1, 'Bing', nil, 'Bing Crosby', 2, nil, 'Bacon', 'Kevin Bacon', 3].each_slice(4).map{ |x,y,z,id| Ped.new(x,y,z,id) }

filter_criteria = lambda { |ped| ped.first_name.nil? or ped.last_name.nil? }

peds.find_all(&filter_criteria).each { |ped| p ped }

输出:

#<struct Ped first_name="Bing", last_name=nil, full_name="Bing Crosby", id=2>
#<struct Ped first_name=nil, last_name="Bacon", full_name="Kevin Bacon", id=3>

用另一个 Proc/lambda 更改 filter_criteria 以更改过滤。另一种方法是将 find_all 包装在一个方法中以获取如下过滤块:

def filter list, &criteria
  list.find_all(&criteria)
end

filter(pedlist) { |ped| some filter criteria }.each { |ped| do something }

然后可以根据需要使用生成的枚举。

于 2012-11-16T18:42:20.733 回答