SetString (System function): Difference between revisions

From m204wiki
Jump to navigation Jump to search
m (1 revision)
m (Oops lost the newline.)
 
(12 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{Template:System:SetString subtitle}}
{{Template:System:SetString subtitle}}
The <var>SetString</var> shared callable function sets a [[System class#System and subsystem globals and strings|system-wide string]].
The <var>SetString</var> shared [[Notation conventions for methods#Callable functions|callable]] function sets a [[System class#System and subsystem globals and strings|system-wide string]].


==Syntax==
==Syntax==
{{Template:System:SetString syntax}}
{{Template:System:SetString syntax}}
===Syntax terms===
===Syntax terms===
<table class="syntaxTable">
<table class="syntaxTable">
<tr><th>%number</th><td>A numeric result that indicates whether the string update succeeded.  <var class="term">%number</var> is set to 1 upon success. If <var class="term">oldValue</var> is specified and does not match the current setting of the string, the update is not performed and a 0 is returned.</td></tr>
<tr><th>%number</th><td>A numeric result that indicates whether the string update succeeded.  <var class="term">%number</var> is set to 1 upon success. If <var class="term">oldValue</var> is specified and does not match the current setting of the string, the update is not performed and a 0 is returned.</td></tr>
<tr><th><var>%(System)</var></th>
 
<td>The class name in parentheses denotes a [[Notation conventions for methods#Shared methods and constructors|shared]] method. <var>SetString</var> can also be invoked via a <var>System</var> object variable, which may be <var>null</var>.</td></tr>
<tr><th><var class="nobr">%(System)</var></th>
<td>The class name in parentheses denotes a [[Notation conventions for methods#Shared methods|shared]] method. <var>SetString</var> can also be invoked via a <var>System</var> object variable, which may be <var>null</var>.</td></tr>
 
<tr><th>name</th>
<tr><th>name</th>
<td>A string that identifies the global string to be set.</td></tr>
<td>A string that identifies the global string to be set.</td></tr>
<tr><th>value</th>
<tr><th>value</th>
<td>A string that identifies the new value for the global string.</td></tr>
<td>A string that identifies the new value for the global string.</td></tr>
<tr><th>oldValue</th>
<tr><th>oldValue</th>
<td>A string that identifies a value to be compared against the current value of the <var>System</var> string before doing the update. This is an optional argument.</td></tr>
<td>A string that identifies a value to be compared against the current value of the <var>System</var> string before doing the update. This is an optional argument.</td></tr>
Line 18: Line 23:


==Usage notes==
==Usage notes==
<ul><li>All errors result in request cancellation.
<ul>
<li>All errors result in request cancellation.
<li>It is not an error to set a string that is not set.
<li>It is not an error to set a string that is not set.
<li>Unlike <var>[[SetGlobal_(System_subroutine)#Usage_notes|SetGlobal]]</var>, <var>SetString</var> does not turn off multiprocessing, and it is designed for fairly high levels of updating.
<li>Unlike <var>[[SetGlobal_(System_subroutine)#Usage_notes|SetGlobal]]</var>, <var>SetString</var> does not turn off multiprocessing, and it is designed for fairly high levels of updating.
Line 24: Line 30:


==Examples==
==Examples==
<ol><li>The following statement sets the system string called DIAMONDS:
<ol>
<li>The following statement sets the system string called <code>DIAMONDS</code>:
<p class="code">%(system):setString('DIAMONDS', 'CLEAR')</p>
<p class="code">%(system):setString('DIAMONDS', 'CLEAR')</p>
<li>The <var class="term">oldValue</var> argument makes it possible to use <var>System</var> strings as structures that can be safely updated by multiple users. For example, one might want to maintain a system-wide counter. This can be accomplished as follows:
<li>The <var class="term">oldValue</var> argument makes it possible to use <var>System</var> strings as structures that can be safely updated by multiple users. For example, one might want to maintain a system-wide counter. This can be accomplished as follows:
<p class="code">%value is longString
<p class="code">%value   is float
%newValue is float
%newValue is float


Line 35: Line 43:
</p>
</p>
Unfortunately, another thread might update the value of the counter between the time the above code retrieves the value (with <var>[[String_(System_function)|String]]</var>) and the time it updates it (with <var>SetString</var>).  In such a case, an increment of the counter might be missed. This is more likely, of course, in an <var class="product">MP/204</var> environment, but you should not count on it being impossible in a non-<var class="product">MP/204</var> environment.  To safely update a counter, you can do the following:
Unfortunately, another thread might update the value of the counter between the time the above code retrieves the value (with <var>[[String_(System_function)|String]]</var>) and the time it updates it (with <var>SetString</var>).  In such a case, an increment of the counter might be missed. This is more likely, of course, in an <var class="product">MP/204</var> environment, but you should not count on it being impossible in a non-<var class="product">MP/204</var> environment.  To safely update a counter, you can do the following:
<p class="code">%value is longString
<p class="code">%value   is float
%newValue is float
%newValue is float
%success is float
%success is float


repeat while not %success
repeat while not %success
   %value = %(system):string('Counter')
   %value = %(system):string('Counter')
   %newValue = %value + 1
   %newValue = %value + 1
   %success = %(system):setString('Counter', %newValue, -
   %success = %(system):setString('Counter', %newValue, %value)
                                            %value)
end repeat
end repeat
</p>
</p>
If no user has updated Counter between the <var>[[String_(System_function)|String]]</var> and the <var>SetString</var> methods, the update would succeed. If some other user has updated it, the update would not be performed, <var>SetString</var> would return a 0, and the repeat loop would be repeated.
If no user has updated <code>Counter</code> between the <var>[[String_(System_function)|String]]</var> and the <var>SetString</var> methods, the update would succeed. If some other user has updated it, the update would not be performed, <var>SetString</var> would return a 0, and the repeat loop would be repeated.
<p>While this looks nasty &amp;amp;amp;amp;#x2014; it seems the code could loop forever &amp;amp;amp;amp;#x2014; it's not that bad. Since the only thing that causes the <var>SetString</var> to fail is another user updating the same string at the same time; even if a hundred users were in this loop, at least one of them would succeed on each iteration. So unless the system is doing almost nothing else, all the updates would be performed in fairly short order.</p>
<p>
While this looks nasty &mdash; it seems the code could loop forever &mdash; it's not that bad. Since the only thing that causes the <var>SetString</var> to fail is another user updating the same string at the same time; even if a hundred users were in this loop, at least one of them would succeed on each iteration. So unless the system is doing almost nothing else, all the updates would be performed in fairly short order.</p>
 
<li>This technique can be used with considerably more complex data-structures. For example, one can actually store a serialized <var>[[XmlDoc_API#The_XmlDoc_class|XmlDoc]]</var> in a <var>system</var> string. A request can retrieve the current structure, manipulate it, and then replace the updated structure:
<li>This technique can be used with considerably more complex data-structures. For example, one can actually store a serialized <var>[[XmlDoc_API#The_XmlDoc_class|XmlDoc]]</var> in a <var>system</var> string. A request can retrieve the current structure, manipulate it, and then replace the updated structure:
<p class="code">%value is longString
<p class="code">%value   is longString
%newValue is longString
%newValue is longString
%myDoc is object xmlDoc
%myDoc   is object xmlDoc
%success is float
%success is float


Line 65: Line 74:
</p>
</p>
Note that the above code assumes that the <code>Complicated</code> system string is already set. If the application cannot guarantee that <code>Complicated</code> has been set, there should be a test for the null string, bypassing the <var>[[LoadXml_(XmlDoc/XmlNode_function)|loadXml]]</var> operation and instead populating the <var>XmlDoc</var> with some initial nodes.
Note that the above code assumes that the <code>Complicated</code> system string is already set. If the application cannot guarantee that <code>Complicated</code> has been set, there should be a test for the null string, bypassing the <var>[[LoadXml_(XmlDoc/XmlNode_function)|loadXml]]</var> operation and instead populating the <var>XmlDoc</var> with some initial nodes.
<p>The document is stored in the system string in EBCDIC. This is not necessary &amp;amp;amp;amp;#x2014; the document could be stored in UTF-8 encoding &amp;amp;amp;amp;#x2014; it is just easier to debug this code if it is saved in EBCDIC.</p>
<p>
The document is stored in the system string in EBCDIC. This is not necessary &mdash; the document could be stored in UTF-8 encoding &mdash; it is just easier to debug this code if it is saved in EBCDIC.</p>
</ol>
</ol>


==See also==
==See also==
{{Template:System:SetString footer}}
{{Template:System:SetString footer}}

Latest revision as of 22:32, 23 October 2015

Set a system-wide string (System class)

The SetString shared callable function sets a system-wide string.

Syntax

[%number =] %(System):SetString( name, value, [oldValue])

Syntax terms

%numberA numeric result that indicates whether the string update succeeded. %number is set to 1 upon success. If oldValue is specified and does not match the current setting of the string, the update is not performed and a 0 is returned.
%(System) The class name in parentheses denotes a shared method. SetString can also be invoked via a System object variable, which may be null.
name A string that identifies the global string to be set.
value A string that identifies the new value for the global string.
oldValue A string that identifies a value to be compared against the current value of the System string before doing the update. This is an optional argument.

Usage notes

  • All errors result in request cancellation.
  • It is not an error to set a string that is not set.
  • Unlike SetGlobal, SetString does not turn off multiprocessing, and it is designed for fairly high levels of updating.

Examples

  1. The following statement sets the system string called DIAMONDS:

    %(system):setString('DIAMONDS', 'CLEAR')

  2. The oldValue argument makes it possible to use System strings as structures that can be safely updated by multiple users. For example, one might want to maintain a system-wide counter. This can be accomplished as follows:

    %value is float %newValue is float %value = %(system):string('Counter') %newValue = %value + 1 %(system):setString('Counter', %newValue)

    Unfortunately, another thread might update the value of the counter between the time the above code retrieves the value (with String) and the time it updates it (with SetString). In such a case, an increment of the counter might be missed. This is more likely, of course, in an MP/204 environment, but you should not count on it being impossible in a non-MP/204 environment. To safely update a counter, you can do the following:

    %value is float %newValue is float %success is float repeat while not %success %value = %(system):string('Counter') %newValue = %value + 1 %success = %(system):setString('Counter', %newValue, %value) end repeat

    If no user has updated Counter between the String and the SetString methods, the update would succeed. If some other user has updated it, the update would not be performed, SetString would return a 0, and the repeat loop would be repeated.

    While this looks nasty — it seems the code could loop forever — it's not that bad. Since the only thing that causes the SetString to fail is another user updating the same string at the same time; even if a hundred users were in this loop, at least one of them would succeed on each iteration. So unless the system is doing almost nothing else, all the updates would be performed in fairly short order.

  3. This technique can be used with considerably more complex data-structures. For example, one can actually store a serialized XmlDoc in a system string. A request can retrieve the current structure, manipulate it, and then replace the updated structure:

    %value is longString %newValue is longString %myDoc is object xmlDoc %success is float repeat while not %success %value = %(system):string('Complicated') %myDoc = new %myDoc:loadXml(%value) ... manipulate myDoc %newValue = %myDoc:serial(,'EBCDIC') %success = %(system):setString('Complicated', - %newValue, %value) end repeat

    Note that the above code assumes that the Complicated system string is already set. If the application cannot guarantee that Complicated has been set, there should be a test for the null string, bypassing the loadXml operation and instead populating the XmlDoc with some initial nodes.

    The document is stored in the system string in EBCDIC. This is not necessary — the document could be stored in UTF-8 encoding — it is just easier to debug this code if it is saved in EBCDIC.

See also