Reputation: 323
I'm doing a course to learn Ruby. Everything's going well except I can't wrap my head around this block behavior.
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
Code that doesn't pass:
def adder(x)
yield + x
end
Another code that doesn't pass:
def adder x
x = 1
yield + x
end
Code that passes:
def adder x = 1
yield + x
end
To me, both non-passing codes make logical sense. I've tried searching online for a reason the last one passes and the others don't, but I haven't had any luck. Can anyone explain why?
Thank you.
Upvotes: 1
Views: 84
Reputation: 2359
First of all, the should
api is deprecated in rspec 3, you should use expect
instead.
the first method definition does not pass because the adder
method expect an argument, but the first spec example does not pass any.
the second definition does not pass the second example, because it ignores the argument passed.
the third definition is the correct one in this case, because if the caller does not pass an argument, x
takes the default value 1
, but if it passes a argument than the parameter x
will take that value. and Thus both examples will pass.
Upvotes: 0
Reputation: 91
There are a couple problems,
In the first example, 'x' has no default value, so it won't automatically increment it by one. It should pass if you pass in 1 as an argument, though.
adder(1) do
5
end
will return 6. It should be passing the second test, but failing the first.
In the second example, 'x' will be set to 1 regardless of what the argument passed in is, so the second test will always fail - it takes in an argument and then immediately disregards it. This means it will pass for the first test, but not the second.
In the third example, it takes in a default value for x, but reassigns it if an argument is passed in, so it passes both tests.
Upvotes: 3
Reputation: 1854
For both the first and second methods, x
doesn't have a default value in the method declaration. The first test would not supply one, raising an ArgumentError
.
The third method includes a default value for x
in the method declaration, allowing it to be called with 0 or 1 arguments. Both adder
(defaults to 1) and adder(2)
are equally valid.
Upvotes: 3