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

ブロックを渡す「ステートメント」を渡さないでください。渡されたブロックは、proc を介して呼び出される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>

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 }

結果の列挙型は、必要に応じて使用できます。

于 2012-11-16T18:42:20.733 に答える