Ruby Programming/Here documents
建立多行的字串时,Ruby支援here documents,一个来自于Bourne shell的功能,而且在Perl与PHP也都支援此功能。
Here documents
[编辑]建构一个here document,则得用<<
运算子跟随著一个识别字用以辨别here document的结束。结尾标签称之为终止者。在终止者之前的每行文字都会被视为是here document的内容,包含任何换行与其它的空白。
puts <<GROCERY_LIST
Grocery list
------------
1. Salad mix.
2. Strawberries.*
3. Cereal.
4. Milk.*
* Organic
GROCERY_LIST
Grocery list
------------
1. Salad mix.
2. Strawberries.*
3. Cereal.
4. Milk.*
* Organic
GROCERY_LIST
结果:
$ grocery-list.rb Grocery list ------------ 1. Salad mix. 2. Strawberries.* 3. Cereal. 4. Milk.* * Organic
If we pass the puts
function multiple arguments, the string literal created from the here document is inserted into the argument list wherever the <<
operator appears. In the code below, the here-document (containing the four grocery items and a blank line) is passed in as the third argument. We get the same output as above.
puts 'Grocery list', '------------', <<GROCERY_LIST, '* Organic' 1. Salad mix. 2. Strawberries.* 3. Cereal. 4. Milk.* GROCERY_LIST
You can also have multiple here documents in an argument list. We added a blank line at the end of each here document to make the output more readable.
puts 'Produce', '-------', <<PRODUCE, 'Dairy', '-----', <<DAIRY, '* Organic' 1. Strawberries* 2. Blueberries PRODUCE 1. Yogurt 2. Milk* 3. Cottage Cheese DAIRY
The result:
$ grocery-list.rb Produce ------- 1. Strawberries* 2. Blueberries Dairy ----- 1. Yogurt 2. Milk* 3. Cottage Cheese * Organic
We have been using the puts
function in our examples, but you can pass here documents to any function that accepts Strings.
Indenting
[编辑]If you indent the lines inside the here document, the leading whitespace is preserved. However, there must not be any leading whitepace before the terminator.
puts 'Grocery list', '------------', <<GROCERY_LIST 1. Salad mix. 2. Strawberries. 3. Cereal. 4. Milk. GROCERY_LIST
The result:
$ grocery-list.rb Grocery list ------------ 1. Salad mix. 2. Strawberries. 3. Cereal. 4. Milk.
If, for readability, you want to also indent the terminator, use the <<-
operator.
puts 'Grocery list', '------------', <<-GROCERY_LIST 1. Salad mix. 2. Strawberries. 3. Cereal. 4. Milk. GROCERY_LIST
Note, however, that the whitespace before each line of text within the here document is still preserved.
$ grocery-list.rb Grocery list ------------ 1. Salad mix. 2. Strawberries. 3. Cereal. 4. Milk.
Quoting rules
[编辑]You may wonder whether here documents follow single-quoting or double-quoting rules. If there are no quotes around the identifier, like in our examples so far, then the body of the here document follows double-quoting rules.
name = 'Charlie Brown' puts <<QUIZ Student: #{name} 1.\tQuestion: What is 4+5? \tAnswer: The sum of 4 and 5 is #{4+5} QUIZ
The result:
$ quiz.rb Student: Charlie Brown 1. Question: What is 4+5? Answer: The sum of 4 and 5 is 9
Double-quoting rules are also followed if you put double quotes around the identifier. However, do not put double quotes around the terminator.
puts <<"QUIZ" Student: #{name} 1.\tQuestion: What is 4+5? \tAnswer: The sum of 4 and 5 is #{4+5} QUIZ
To create a here document that follows single-quoting rules, place single quotes around the identifier.
puts <<'BUS_SCHEDULES' c:\napolean's documents\tomorrow's bus schedule.txt c:\new documents\sam spade's bus schedule.txt c:\bus schedules\the #9 bus schedule.txt BUS_SCHEDULES
The result:
$ bus-schedules.rb c:\napolean's documents\tomorrow's bus schedule.txt c:\new documents\sam spade's bus schedule.txt c:\bus schedules\the #9 bus schedule.txt