2014-05-01 33 views
-2

我创建了一个名为imap_query的lambda,它包装了一个方法调用的调用,我需要在下面的代码中进行两次调用。将可选块传递给内联lambda

我第一次调用imap_query lambda时,我不想传入一个块,因为我只想要返回google.email.find函数调用的值。

第二次我打电话imap_query拉姆达,我想通过一个块。

def process_emails(user, google, folder) 
    since_time = Net::IMAP.format_date 1.day.ago 

    imap_query = -> { 
         google.email.find(mailbox: folder, read_only: true, count: max_emails, keys: [ 'RECENT', 'SINCE', since_time ]) 
        } 

    @email_total = imap_query().size 

    return finish_sync(user) if @email_total == 0 

    # how do I pass a block to the imap_query lambda 
    imap_query.call() do |mail, imap, uid| 
     update_progress user 
     yield mail, imap, uid 
    end 
    end 

我所挣扎的是:

  1. 如何与可选块参数声明拉姆达。
  2. 如何调用拉姆达和传递块,如果我想传递一个中。
+0

为什么呢? –

+0

除了我的好奇心外,其实没有什么好的理由,一种方法会很好,我会如何将可选块传递给一个方法? 我想避免的是将参数列表复制到google.email.find – dagda1

回答

1

在红宝石每一个方法可以采取块。当写

def foo(i) 
    puts i 
end 

您也可以拨打

foo 1 do puts "a block" end 

没有一个错误。

您也可以使用block_given? Kernel方法来识别是否将块传递给方法。

def bar(i) 
    puts i 
    if block_given? 
    puts "a block" 
    yield 
    else 
    puts "no block" 
    end 
end 

其中

bar 1 
#=> 1 
#=> no block 

bar 1 do puts "Yippie a block" end 
#=> 1 
#=> a block 
#=> Yippie a block 

这样做的另一种方式是与&block参数要使用lambda代替的方法

def baz(i, &block) 
    puts i 
    block.call unless block.nil? 
end 

baz 1 
#=> 1 
baz 1 do puts "a block" end 
#=> 1 
#=> a block