1

I noticed the difference in printing array with and without interpolation:

Source code:

uuu="a b c d e f g";
o=uuu.split(' ');

puts "Interpolation:#{o}";

puts "Without interpolation";
puts o;

Output:

Interpolation:["a", "b", "c", "d", "e", "f", "g"]
Without interpolation
a
b
c
d
e
f
g

I don't understand why those differences happen.

2 Answers 2

2

When you call puts in the main context without an explicit receiver, you are calling Kernel#puts, and that calls $stdout.puts. Usually, $stdout.puts outputs the result of applying to_s to its argument. However, array is exceptional in that each element of it is printed in a separate line. From the doc:

puts(obj, ...) → nil Writes the given objects to ios as with IO#print. Writes a record separator (typically a newline) after any that do not already end with a newline sequence. If called with an array argument, writes each element on a new line. If called without arguments, outputs a single record separator.

In your first example, you interpolated a string with an array, which applies to_s to it, and ends up with a string of the format ["a", "b", ...], which is passed to puts. In your second example, you passed an array directly to puts, to which the exceptional behaviour on arrays explained above applies.

Sign up to request clarification or add additional context in comments.

Comments

1

This doesn't really have anything to do with how interpolation behaves. It's not interpolation that's giving you a difference in output, it's that your supply a string vs an array to puts.

The same results occur if you simply do this:

puts o.to_s
puts o

puts handles strings and arrays differently. In the first instance, you're giving it a string, into which an array has been interpolated. Interpolation invokes to_s on the value being interpolated, and when you invoke to_s on an array, it gives you the format you see in your output. For example [1, 2, 3].to_s is the string "[1, 2, 3]".

When you give puts an array as its argument, it prints the items in the array, one per line.

8 Comments

Inside "#{..}.. we can also put chunk of code.. It evaluated.. Does that mean there also #to_s applied. So I think your interpolation explanation not correct..
@ArupRakshit Yes, and the result of your chunk of code has to_s invoked on it, unless it evaluates to a string. See rubyfiddle.com/riddles/c14be
@ArupRakshit Try: class Fixnum; def to_s; "WHAT"; end; end; puts "#{3 * 4}"
I tested the same but differently - class Fixnum undef to_s end "#{1}" # => NoMethodError)... You are correct.
@ArupRakshit and meagar: ruby -e 'class Fixnum; def to_s; "WHAT"; end; end; puts 42.to_s; puts "#{3 * 4}"' Output: WHAT and 12.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.