I know the following recursion example works properly as minus(start - 1)
. However I'm trying to understand why the adding a puts
outputs
and p
outputs nil
.
If my understanding is correct the recursion starts with the last stack frame pushed, which would evaluate to 2, then 1, then 0. Does this have to do with outputting an expression that has no definite value?
def minus(start)
puts start
if start > 0
puts minus(start - 1)
end
end
minus(3)
3
2
1
0
CodePudding user response:
It is because how puts
and p
works.
When we use puts
it calls to_s
from the object.
When we use p
it calls inspect
from the object.
With nil
:
nil.to_s # ''
nil.inspect # 'nil'
puts nil # It will use to_s and the result will be ''
p nil # It will use inspect and the result will be 'nil'
CodePudding user response:
When there is no explicit return
in Ruby then a method returns the value returned by the last expression in the method.
The return value of the expression minus(start - 1)
would be whatever is returned by the minus
method.
But the return value of puts minus(start - 1)
would always be nil
because that is how the puts
method is specified. Quote from the docs:
puts(obj, ...)
→ `nil``Writes the given object(s) to ios. Writes a newline after any that do not already end with a newline sequence. Returns
nil
.
That said because the return value of all recursive calls to minus
is nil
in your examples this nil
is outputted. And – as rowend already explained – puts nil
calls to_s
on nil
and therefore outputs an empty string. Whereas p
calls inspect
on the nil
and therefore outputs nil
.