将可选块传递给内联lambda

时间:2014-05-01 09:30:11

标签: ruby

我在下面创建了一个名为imap_query的lambda,它包含对方法调用的调用,我需要在下面的代码中进行两次。

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

第二次调用imap_query lambda时,我想传递一个块。

  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

我正在努力的是:<​​/ p>

  1. 如何使用可选的块参数声明lambda。
  2. 如果我想传入一个块,如何调用lambda并传入一个块。

2 个答案:

答案 0 :(得分:1)

ruby​​中的每个方法都可以占用一块。写作时

def foo(i)
  puts i
end

您也可以致电

foo 1 do puts "a block" end

没有错误。

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

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 参数

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

答案 1 :(得分:0)

我试图做类似的事情时遇到了这个问题。一对评论:

a)我对原始问题感到困惑,因为对imap_query的第二次调用给出了一个期望参数的块,但我不清楚参数的传递位置。

b)imap_query lambda使用&#39; max_emails&#39;我在任何地方都看不到的变量。

关于问题:

  1. 从我对Proc#call的阅读中,不支持在Proc对象上将块传递给#call
  2. 虽然我不认为可以将块传递给Proc,但 可以将(可选的)Proc传递给另一个Proc(类似于@ xlembouras&#39;最后一个例子,但是使用Proc与方法)
  3. 例如:

    >> a = ->(b=nil) { puts :a; b.call if b }
    >> b = ->{ puts :b }
    >> a.call()
    a
    => nil
    >> a.call(b)
    a
    b
    => nil
    

    >> a = ->(b=nil) { puts :a; b.call(1,2,3) if b }
    => #<Proc:0x007fc573a917e0@(irb):41 (lambda)>
    >> b = ->(*args){ puts :b; puts args.join(',') }
    => #<Proc:0x007fc5734088d8@(irb):42 (lambda)>
    >> a.call()
    a
    => nil
    >> a.call(b)
    a
    b
    1,2,3
    => nil