lambda和begin block有什么区别?

时间:2010-08-26 21:32:58

标签: ruby rspec rake

我正在尝试验证在执行将引发异常的rake任务后是否已将文本写入文件(build.log)。检查下面的代码片段,开头的代码片段,而lambda抛出一条消息,说它无法找到build.log文件。

使用开始测试。(有效)

  begin 
     Rake::Task['git:checkout'].invoke //writes "destination already exists" to build.log
  rescue
  end
  IO.read(@project_folder+@build_id+"/build.log").should match(/.*destination.*already.*exists.* /)   

尝试使用lambda测试相同的内容。 (不起作用)

  lambda {
    Rake::Task['git:checkout'].invoke //writes "destination already exists" to build.log
  }
  IO.read(@project_folder+@build_id+"/build.log").should match(/.*destination.*already.*exists.* /) 

这两者有什么区别?

1 个答案:

答案 0 :(得分:5)

你正在考虑lambda错误。 lambda是可运行代码的暂停。我说暂停了,因为它已经准备好运行,甚至准备好接受争论,但它实际上还没有完成任何事情。

例如,请考虑以下(传递)规范:

flag = false
x = lambda {            # Here, we suspend a function to set our flag.
  flag = true
}

flag.should == false    # The code in the lambda is still suspended;
                        # it hasn't done any work.

x.call                  # Now we ran the suspended function.
flag.should == true

注意两件事:

  1. 我从lambda关键字中获得了一个对象。你也得到了这个对象,但由于你没有将它分配给变量,它会立即丢失。 ;)
  2. 我使用call方法实际执行暂停中的代码(即在lambda中)。在您给出的示例中,您实际上根本没有运行git:checkout任务!
  3. begin ... rescue ... end是一种完全不同的机制:目的是正确处理(或在您的情况下,吞下)异常。坚持这种形式;它是唯一能满足您需求的产品。 :)