action
new shelf-name ({string-expression})? insertion-point? set new shelf-name ({ string-expression})? insertion-point? to expression
Argument definitions
new
inserts a new item onto a shelf and can only be invoked on shelves that have been declared variable
:
local integer x variable initial-size 0 new x
By default, the new item is inserted after the last item on the shelf. You can insert the new item before or after another item:
new x{"wilma"} after [2]
To make the new item the first item on the shelf, you can use before [1]
or after [0]
.
A new item can be given a key as it is inserted:
new x{"fred"} before {"barney"} new x{"wilma"} after [2]
The set new
action combines the new
and set
actions into one action so that
new x{"fred"} before [1] set x{"fred"} to "flintstone0"can be replaced with:
set new x{"fred"} before [1] to "flintstone0"
Putting these code fragments together gives us the following program:
process local stream x variable initial-size 0 new x set key of x to "barney" set x to "flintstone1" set new x{"fred"} before [1] to "flintstone0" set x{"fred"} to "flintstone0" new x{"wilma"} after [2] set x{"wilma"} to "flintstone2" repeat over x output x || " has key " || key of x || "%n" again ; Output: "flintstone0 has key fred ; flintstone1 has key barney ; flintstone2 has key wilma"
The new
operator can now be used wherever you refer to a shelf item. OmniMark has always allowed the use of new
with the set statement:
process local integer foo variable set new foo to 17 output 'd' % foo
Now you can use new
whenever you refer to a shelf item, for example, in an increment statement:
process local integer my-numbers variable increment new my-numbers
Here the new
action creates a new item on the my-numbers shelf and then the increment action increments it.
OmniMark does not allow you to add a new item to a shelf if the key you specify already exists on the shelf. With previous versions of OmniMark it was necessary to test for this conflict to avoid a program error:
local integer my-numbers variable ... new my-numbers when my-numbers has key "my-key" increment my-numbers {"my-key"}In OmniMark 8, you can use the guarded form of
new
to express this logic much more succinctly. The guarded form of new
is new?
:
local integer my-numbers variable ... increment new? my-numbers {"my-key"}
The guarded form of new
is used only when creating a keyed item. If a key is not specified, an error will occur.
The following example shows how you can use new?
to easily remove duplicates from a data set. The following is a list of index entries with page references. The problem is to remove the duplicate entries, but also to maintain a count of the duplicates as an indication of when a topic is most heavily discussed. The data is as follows:
OmniMark 1 streaming 2 OmniMark 4 OmniMark 4 streaming 4
Using the guarded new operator, this problem is easily solved like this:
declare record usage-type field integer reference variable global usage-type usage variable find letter+ => word blank digit+ => page "%n" increment new? (new? usage {word}):reference {page} process submit #main-input repeat over usage output key of usage repeat over usage:reference as page-ref output ',' unless #first output ' ' || key of page-ref || " (%d(page-ref))" again output "%n" again
The inner guarded new
of the find rule's increment action creates a new word entry if the word has not been encountered. The outer guarded new
creates a new page reference if the page has not been encountered and then it passes the page entry, new or otherwise, to increment, which increases its count. The output of this program when given the input above is:
OmniMark 1 (1), 4 (2) streaming 2 (1), 4 (1)
It is the following line that illustrates the power of guarded new
and the ability to use new
in any context:
increment new? (new? usage {word}):reference {page}
Written in the old style, this one line would require the following:
new usage {word} unless usage has key word new usage{word}:reference {page) unless usage{word}:reference has key page increment usage{word}:reference {page)