lambda 和 begin 块有什么区别?

发布于 2024-09-16 19:20:00 字数 667 浏览 3 评论 0原文

我试图在执行 rake 任务后验证文本是否已写入文件(build.log),这将引发异常。查看下面的两个代码片段,带有 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.* /) 

这两者有什么区别?

I am trying to verify if a text have been written to file (build.log) after executing a rake task which will throw an exception. Checkout both the code snippets below, the one with begin works whereas lambda throws a message saying it couldn't find the build.log file.

Using begin to test.(works)

  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.* /)   

Trying to test the same using lambda. (Not works)

  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.* /) 

What is the difference between these two?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

月亮邮递员 2024-09-23 19:20:00

您对 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 是一种完全不同的机制:目的是正确处理(或者在您的情况下,吞咽)异常。坚持这种形式;它是唯一能满足您需求的产品。 :)

You're thinking of lambda incorrectly. A lambda is a suspension of runnable code. I say suspended, because it's ready to run, even ready to take arguments, but it hasn't actually done anything yet.

For example, consider the following (passing) spec:

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

Notice two things:

  1. I got an object out of the lambda keyword. You're getting this object, too, but since you don't assign it to a variable it's immediately lost. ;)
  2. I used the call method to actually execute the code in the suspension (i.e. in the lambda). In your given example, you aren't actually running your git:checkout task at all!

begin ... rescue ... end is a completely different mechanism: the purpose is to correctly handle (or in your case, to swallow) exceptions. Stick with this form; it's the only one that does what you need. :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文