|  | 
 | ||||
|        | |||||
|  | |||||
| Prerequisite Concepts | Related Syntax | ||||
| Output scopes | |||||
 OmniMark distinguishes the act of creating output from the act of selecting the output destination, meaning that
      the stream that receives the output data does not have to be lexically in scope for you
      to output to it. Instead, a stream or a string sink can be placed in an output execution
        scope. While a stream is in the current output scope, all output statements will output to it
      regardless of the lexical scope they occur in.
    
You can use the keywords using output as to create an output scope and to place a stream variable
      into that output scope. Like any other kind of scope, output scopes can be nested:
  process
      local stream foo
      open foo as file "foo.txt"
      using output as foo
      do
          output "<rhyme>"
          submit "Mary had a little lamb"
          output "</rhyme>"
      done
      
  find ("Mary" | "lamb") => person
      local stream foo
      reopen foo as file "foo2.txt"
      using output as foo
        output "<person>" || person || "</person>"    
    
Here a new output scope is established in the find rule, causing the material output in the find rule to be sent to a different destination. This output scope is nested inside the output scope created in the process rule. This scope becomes the current output scope again as soon as the find rule exits.
You can also place a stream into the current output scope, without creating a new output scope, using
      output-to:
  global stream foo 
  global stream bar
      
  process
      open foo as buffer
      open bar as buffer
      using output as foo
          submit "Mary had a little lamb"
      close foo
      close bar
      output "Foo contains: " || foo
      output "%nBar contains: " || bar
          
  find " a "
      output-to bar
    
This program outputs the following:
Foo contains: Mary had Bar contains: little lamb
The output-to in the find rule resets the destination of the output scope established by the using output
        as in the process rule. Thus the rest of the text goes to the new destination. 
    
In general, you should use using output as rather then output-to, but
      output-to is useful in certain situations, especially when the destination of data is determined by
      examining the data itself.
    
Consider a piece of XML that might be used to send files across a network. It encapsulates the name of the file
      and its contents inside "name" and encapsulates "data" elements inside a "file" element:
<file> <name>myfile.txt</name> <data>The content of the file.</data> </file>
We can process this with the following program:
  global stream file-data
  process 
      do xml-parse document
          scan file "files.xml"
          suppress
      done
      
  element file
      suppress
      close file-data
      
  element name
      open file-data as file "%c"
      output-to file-data
      
  element data
      output "%c"
    
Here the entire processing of the XML is done in a single output scope, but every time we find a filename in the
      input we change the destination of the current output scope. It would be difficult to do the same thing with
      using output as, because the "data" element is not nested inside the "filename" element, so an output
      scope established in the "name" element would have expired before the "data" element was processed.
    
(By the way, the example shows poor XML language design. It would have been better to make the filename an attribute of the "file" element. But you can't always control the format of the data you have to process.)
If you use output-to, note that placing a stream into an output scope does not exempt it from the
      rules of lexical scoping when it comes to the life span of variables. Local variables are created when their
      lexical scope enters execution scope and destroyed when their lexical scope leaves execution scope. It is an error
      to allow a local variable to go out of execution scope while it is still in an output scope. You will avoid this
      problem if you stick to using using output as to create output scopes.
| Prerequisite Concepts | Related Syntax | 
Copyright © Stilo International plc, 1988-2008.