Ruby Programming/Here documents

维基教科书,自由的教学读本

← Strings | ASCII →

建立多行的字串時,Ruby支援here documents,一個來自於Bourne shell的功能,而且在PerlPHP也都支援此功能。

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