簡體   English   中英

如何將語句作為參數傳遞給方法中的塊?

[英]How do I pass a statement as an argument to a block within a method?

我正在嘗試弄清楚如何將語句作為方法參數傳遞-用作塊過濾條件的一部分。 例如,我有以下代碼:

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

我對此表示贊賞。

您沒有通過“聲明”,而是通過了塊。 傳遞的塊通過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? }
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 }

然后可以根據需要使用結果枚舉。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM