10

I am calling to_s within a method:

$  def my_function(num)
$    number = num.to_s.split(//)
$    puts number
$  end

$  my_function(233)
2
3
3
# => nil

It looks to me like within the function, no array is created since the output is nil. Why is an array of strings not created when to_s.split(//) is called inside a method?

Also, why is the output for puts number seemingly just each digit on its own line? Do I need to explicitly create the array within the function and then explicitly push the split number into it?

sawa
  • 165,429
  • 45
  • 277
  • 381
Alec Wilson
  • 566
  • 1
  • 7
  • 18

3 Answers3

12

When you call puts on an array, it outputs each element of the array separately with a newline after each element. To confirm that your to_s methods are converting the number to a string, try using print instead of puts.

As for the nil that's output, that is the return value of your function. Unless there is an explicit return, the return value of a function will be the evaluation of the last line, which in your case is: puts number. The return value of puts number is nil; printing the value of number is a side effect, not the return value.

I'm curious as to why the output was indeed an array in your first lines of code (not within the function):

$  num = 233
$  number = num.to_s.split(//)
$  puts number
=> ['2', '3', '3']

I suspect that you actually saw that output after the num.to_s.split(//) line, not the puts number line.

sawa
  • 165,429
  • 45
  • 277
  • 381
dwenzel
  • 1,404
  • 9
  • 15
5

Your function is calling puts number. That will display it, not return it. puts returns nil which is why your call to my_function(233) is returning nil. The reason that the output is a single number on each line is because that is what puts does when an array is passed to it. One element per line.

Try this code:

puts [1,2,3]

puts '=' * 40

def my_function(num)
  num.to_s.split(//)
end

x =  my_function(233)

p x

When run the output is:

1
2
3
========================================
["2", "3", "3"]

The key difference is that my_function no longer displays any output. It just returns the result. It's important to remember that a ruby method will return the last evaluated statement as it's result. That is to say the above method is the same as this:

def my_function(num)
  return num.to_s.split(//)
end
Philip Hallstrom
  • 19,673
  • 2
  • 42
  • 46
  • Thank you. That was very helpful. I was relying on implicit returns, not realizing I was overriding them with puts. That solved it. – Alec Wilson Feb 26 '15 at 01:27
3

The array you see in your first snippet is the result of the evaluation of the split function. Try this outside of the function : puts [1,2,3] , and you'll see that the results didn't vary.

Use print if you want it to print it the cute way.

Best regards

earthb0und
  • 111
  • 5