【问题标题】:What's the difference between lambda and begin block?lambda 和 begin 块有什么区别?
【发布时间】:2010-08-26 21:32:57
【问题描述】:

我正在尝试在执行将引发异常的 rake 任务后验证是否已将文本写入文件 (build.log)。检查下面的代码 sn-ps,带有 begin 的代码有效,而 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.* /) 

这两者有什么区别?

【问题讨论】:

    标签: ruby rspec rake


    【解决方案1】:

    您对 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 任务!

    begin ... rescue ... end 是一种完全不同的机制:目的是正确处理(或在您的情况下,吞下)异常。坚持这种形式;它是唯一能满足您需求的产品。 :)

    【讨论】:

    • 非常感谢。你的回答澄清了我的困惑。
    猜你喜欢
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 2015-09-21
    • 2015-10-14
    • 1970-01-01
    • 2019-01-15
    • 1970-01-01
    • 2010-10-20
    相关资源
    最近更新 更多