6

I have found this code block on Wikipedia as an example of a quine (program that prints itself) in Ruby.

puts <<2*2,2
puts <<2*2,2
2

However, I do not get how it works. Especially, what I do not get is that when I remove the last line, I get this error:

syntax error, unexpected $end, expecting tSTRING_CONTENT or tSTRING_DBEG or tSTRING_DVAR or tSTRING_END

What happens in those lines?

Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
knub
  • 3,892
  • 8
  • 38
  • 63

2 Answers2

6

The <<something syntax begins a here-document, borrowed from UNIX shells via Perl - it's basically a multiline string literal that starts on the line after the << and ends when a line starts with something.

So structurally, the program is just doing this:

puts str*2,2

... that is, print two copies of str followed by the number 2.

But instead of the variable str, it's including a literal string via a here-document whose ending sentinel is also the digit 2:

puts <<2*2,2
puts <<2*2,2
2

So it prints out two copies of the string puts <<2*2,2, followed by a 2. (And since the method used to print them out is puts, each of those things gets a newline appended automatically.)

Mark Reed
  • 91,912
  • 16
  • 138
  • 175
  • But if the end marker of the string is the "something" after `<<`, shouldn't it be `2*2,2` sequence then, and the same sequence used in the last line to end it? – SasQ Aug 09 '12 at 05:06
  • The precedence of `<<` is tighter than `*`, so `<<2*2` is "the string represented by the following 2-terminated here document, multiplied by 2" rather than "the string represented by the following 2*2-terminated here document." – Mark Reed May 17 '16 at 13:40
2

In ruby, you can define strings with

str = <<DELIMITER
  long string
  on several
  lines
DELIMITER

I suppose that from here, you can guess the rest :)

ksol
  • 11,835
  • 5
  • 37
  • 64