对Ruby中的块行为感到困惑

时间:2015-03-01 06:34:30

标签: ruby rspec

我正在学习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

对我而言,两个非传递代码都具有逻辑意义。我尝试在线搜索最后一个通过的原因而其他人没有,但我没有运气。任何人都可以解释原因吗?

谢谢。

3 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:3)

有几个问题,

在第一个示例中,'x'没有默认值,因此它不会自动将其递增1。但是,如果你传入1作为参数,它应该通过。

adder(1) do
  5
end

将返回6.应该通过第二次测试,但是第一次测试失败。

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

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

答案 2 :(得分:0)

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

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

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