block inside interpolation with ruby

1k views Asked by At

I'm writing a simple program that asks the user for input for an array and spits out the array and its average. Really easy and I had no issues with it.

In the end I came up with: (in this example I'll just use a random array instead of the code for the user input)

array = [1,2,3]
sum = array.inject(:+)
average = sum.to_f/array.length
puts "The numbers you entered in the array were: #{array.join(" ")}"
puts "The average of those numbers are: #{average}"

The output is expected and gives me:

The numbers you entered in the array were: 1 2 3
The averages of those numbers are: 2.0

However, when I was first trying to code this I was trying to be real slick for an easy assignment and I tried doing an interpolation inside of an interpolation. I utilized this code:

For the fourth line in the above code I used:

puts "The numbers you entered in the array were: #{array.each{|num| print "#{num} "}}" 

which outputted:

1 2 3 The numbers you entered in the array were: [1, 2, 3]

So I thought there might have been an issue with doing an interpolation inside a block that was inside of an interpolation. So I then ran the following code to test for just a block inside interpolation.

puts "The numbers you entered in the array were: #{array.each{|num| print num}}"

which outputted:

123The numbers you entered in the array were: [1, 2, 3]

Can anyone explain the me why the proc is executed inside of the interpolation first, printed and then the puts happens. In addition, why did it puts the array in array.inspect form when I never called .inspect on the array.

1

There are 1 answers

5
Jeff Price On BEST ANSWER

The question you want answered

When you use variable interpolation, that value to interpolate is going to resolve before the original string.

In this case, your Array.each is doing it's thing and printing out "1" then "2" and finally "3". It returns the original Array of [1, 2, 3]

output> 123 # note new line because we used print

Now that your interpolation is resolved, the rest of the puts finishes up and uses the returned value of [1, 2, 3] and prints:

output> The numbers you entered in the array were: [1, 2, 3]\n

To get the final output of:

output> 123The numbers you entered in the array were: [1, 2, 3]\n

The question everyone WANTS to answer :)

http://www.ruby-doc.org/core-2.1.4/Array.html#method-i-each

When calling Array.each with a block, the return is self.

This is "bad" in your case, because you don't want self returned. It will always return the same thing, your original array.

puts "The numbers you entered in the array were: #{array.each{|num| num*2}}"
The numbers you entered in the array were: [1, 2, 3] # WAT?

As a Sergio Tulentsev said, use .map and .join

puts "The numbers you entered in the array were: #{array.map{|num| num*2}.join(' ')}"
The numbers you entered in the array were: 2 4 6