对 Ruby 中的块行为感到困惑

Confused about block behavior in Ruby

我正在学习 Ruby 的课程。一切都很顺利,只是我无法理解这种块行为。

RSpec:

describe "adder" do
    it "adds one to the value returned by the default block" do
      adder do
        5
      end.should == 6
    end

    it "adds 3 to the value returned by the default block" do
      adder(3) do
        5
      end.should == 8
    end
  end

未通过的代码:

def adder(x)
    yield + x
end

另一个没有通过的代码:

def adder x
    x = 1
    yield + x
end

通过的代码:

def adder x = 1
    yield + x
end

对我来说,这两个非传递代码都是合乎逻辑的。我曾尝试在线搜索最后一个通过而其他人没有通过的原因,但我没有任何运气。谁能解释一下为什么?

谢谢。

对于第一种和第二种方法,x在方法声明中没有默认值。第一个测试不会提供一个,引发 ArgumentError.

第三种方法在方法声明中包含 x 的默认值,允许使用 0 或 1 个参数调用它。 adder(默认为 1)和 adder(2) 都同样有效。

有几个问题,

在第一个例子中,'x'没有默认值,所以它不会自动加一。不过,如果您将 1 作为参数传入,它应该会通过。

adder(1) do
  5
end

will return 6. 应该会通过第二个测试,但没有通过第一个测试。

在第二个示例中,无论传入的参数是什么,'x' 都将设置为 1,因此第二个测试将始终失败 - 它接受一个参数,然后立即忽略它。这意味着它将通过第一次测试,但不会通过第二次测试。

在第三个示例中,它接受 x 的默认值,但如果传入参数则重新分配它,因此它通过了两个测试。

首先,should api 在 rspec 3 中已弃用,您应该使用 expect 代替。 第一个方法定义没有通过,因为 adder 方法需要一个参数,但是第一个规范示例没有通过任何参数。

第二个定义没有通过第二个例子,因为它忽略了传递的参数。

第三个定义在这种情况下是正确的,因为如果调用者不传递参数,x采用默认值1,但如果它传递参数而不是参数x 将采用该值。因此这两个例子都会通过。