这里的文档
对于长字符串文字,可能没有可以使用的单个字符分隔符而不必担心记住在文字中转义字符。 Ruby 对这个问题的解决方案是允许您指定任意字符序列作为字符串的分隔符。这种文字是从 Unix shell 语法中借用的,在历史上被称为 here document。 (因为文档就在源代码中,而不是在外部文件中。)
此处的文档以<< 或<<- 开头。紧随其后的是指定结束分隔符的标识符或字符串(不允许空格,以防止与左移运算符产生歧义)。字符串文字的文本从下一行开始,一直持续到分隔符的文本单独出现在一行上。例如:
document = <<HERE # This is how we begin a here document
This is a string literal.
It has two lines and abruptly ends...
HERE
Ruby 解释器通过从输入中一次读取一行来获取字符串文字的内容。然而,这并不意味着<< 必须是它自己的行的最后一件事。事实上,在阅读完 here 文档的内容后,Ruby 解释器会回到它所在的行并继续解析它。例如,以下 Ruby 代码通过连接两个 here 文档和一个常规的单引号字符串来创建一个字符串:
greeting = <<HERE + <<THERE + "World"
Hello
HERE
There
THERE
第 1 行的 <<HERE 导致解释器读取第 2 行和第 3 行。<<THERE 导致解释器读取第 4 和 5 行。读取这些行之后,三个字符串文字连接为一个.
here 文档的结束分隔符必须单独出现在一行中:分隔符后面不能有注释。如果此处的文档以<< 开头,则分隔符必须从行首开始。如果文字以 <<- 开头,则分隔符前面可能有空格。此处文档开头的换行符不是文字的一部分,但文档末尾的换行符是。因此,每个here文档都以行终止符结尾,除了一个空的here文档,与""相同:
empty = <<END
END
如果您使用不带引号的标识符作为终止符,如前面的示例中所示,则此处的文档的行为类似于双引号字符串,用于解释反斜杠转义和 # 字符。如果您想非常非常字面化,不允许任何转义字符,请将分隔符放在单引号中。这样做还允许您在分隔符中使用空格:
document = <<'THIS IS THE END, MY ONLY FRIEND, THE END'
.
. lots and lots of text goes here
. with no escaping at all.
.
THIS IS THE END, MY ONLY FRIEND, THE END
分隔符周围的单引号暗示此字符串文字类似于单引号字符串。事实上,这种here文件更加严格。因为单引号不是分隔符,所以永远不需要用反斜杠转义单引号。并且因为从不需要反斜杠作为转义字符,所以从不需要转义反斜杠本身。因此,在这种 here 文档中,反斜杠只是字符串文字的一部分。
您也可以使用双引号字符串文字作为此处文档的分隔符。这与使用单个标识符相同,只是它允许在分隔符内使用空格:
document = <<-"# # #" # This is the only place we can put a comment
<html><head><title>#{title}</title></head>
<body>
<h1>#{title}</h1>
#{body}
</body>
</html>
# # #
请注意,除了在 << 标记之后和文字开头之前的第一行之外,没有办法在 here 文档中包含注释。在这段代码中的所有# 字符中,一个引入了注释,三个插入表达式到文字中,其余的是分隔符