Home > Blockchain >  Why is `puts minus(start - 1)` outputs ` ` and `p minus(start - 1)` outputs `nil`?
Why is `puts minus(start - 1)` outputs ` ` and `p minus(start - 1)` outputs `nil`?

Time:11-22

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.

  • Related