我正在尝试弄清楚如何将语句作为方法参数传递 - 用作块过滤条件的一部分。例如,我有以下代码:
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
我对此表示赞赏。
答案 0 :(得分: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? }
答案 1 :(得分: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>
将filter_criteria更改为另一个Proc / lambda以更改过滤。另一种方法是将find_all包装在一个方法中,以采用如下过滤块:
def filter list, &criteria
list.find_all(&criteria)
end
filter(pedlist) { |ped| some filter criteria }.each { |ped| do something }
然后可以根据需要使用生成的可枚举。