[ nwe help ]
Search Help   »  General   »  MOO  »   JHC  »   Builtin Help

Server Builtin Functions


  abs()                   add_property()          add_verb()
  boot_player()           builtin-index           caller_perms()
  callers()               children()              chparent()
  clear_property()        connected_players()     connected_seconds()
  connection_name()       create()                crypt()
  ctime()                 delete_property()       delete_verb()
  dump_database()         eval()                  idle_seconds()
  index()                 is_clear_property()     is_player()
  kill_task()             length()                listappend()
  listdelete()            listen()                listinsert()
  listset()               match()                 max()
  max_object()            memory_usage()          min()
  move()                  notify()                open_network_connection()
  output_delimiters()     parent()                pass()
  players()               properties()            property_info()
  queued_tasks()          random()                read()
  recycle()               renumber()              reset_max_object()
  rindex()                rmatch()                seconds_left()
  server_log()            server_version()        set_player_flag()
  set_property_info()     set_task_perms()        set_verb_args()
  set_verb_code()         set_verb_info()         setadd()
  setremove()             shutdown()              sqrt()
  strcmp()                strsub()                substitute()
  suspend()               task_id()               ticks_left()
  time()                  tonum()                 toobj()
  tostr()                 typeof()                unlisten()
  valid()                 verb_args()             verb_code()
  verb_info()             verbs()             

abs()

Syntax:  abs (num <x>)   => num

Returns the absolute value of <x>.  If <x> is negative, then the result
is `-<x>'; otherwise, the result is <x>.


add_property()

Syntax:  add_property (obj <object>, str <prop-name>, <value>, list <info>)   => none

Defines a new property on the given <object>, inherited by all of its
descendants; the property is named <prop-name>, its initial value is
<value>, and its owner and initial permission bits are given by <info>
in the same format as is returned by `property_info()'.
If <object> is not valid or <object> already has a property named
<prop-name> or <info> does not specify a legitimate owner and
permission bits, then `E_INVARG' is retuned.  If the programmer does not
have write permission on <object> or if the owner specified by <info>
is not the programmer and the programmer is not a wizard, then `E_PERM' is
returned.


add_verb()

Syntax:  add_verb (obj <object>, list <info>, list <args>)   => none

Defines a new verb on the given <object>.  The new verb's owner, permission
bits and name(s) are given by <info> in the same format as is returned by
`verb_info()'.  The new verb's direct-object, preposition, and indirect-object
specifications are given by <args> in the same format as is returned by
`verb_args()'.  The new verb initially has the empty program associated with 
it; this program does nothing but return an unspecified value.

If <object> is not valid, or <info> does not specify a legitimate owner
and permission bits, or <args> is not a legitimate syntax specification,
then `E_INVARG' is retuned.  If the programmer does not have write
permission on <object> or if the owner specified by <info> is not the
programmer and the programmer is not a wizard, then `E_PERM' is returned.


boot_player()

Syntax:  boot_player (obj <player>)   => none

Immediately terminates any currently-active connection to the given
<player>.  If the programmer is not either a wizard or the same as
<player>, then `E_PERM' is returned.  If there is no currently-active
connection to <player>, then this function does nothing.

If there was a currently-active connection, then the following two verb calls
are made before the connection is closed:

    <player>:disfunc()
    <player>.location:disfunc(<player>)

It is not an error if either of these verbs do not exist; the corresponding
call is simply skipped.


caller_perms()

Syntax:  caller_perms ()   => obj

Returns the permissions in use by the verb that called the currently-executing
verb.  If the currently-executing verb was not called by another verb (i.e., it
is the first verb called in a command or server task), then
`caller_perms()' returns `#-1'.


callers()

Syntax:  callers ()   => list

Returns information on each of the verbs currently waiting to resume execution
in the current task.  When one verb calls another verb, execution of the caller
is temporarily suspended, pending the called verb returning a value.  At any
given time, there could be several such pending verbs: the one that called the
currently executing verb, the verb that called that one, and so on.  The result
of `callers()' is a list, each element of which gives information about
one pending verb in the following format:

    {<this>, <verb-name>, <programmer>, <verb-loc>, <player>}

where <this> is the initial value of the variable `this' in that verb,
<verb-name> is the name used to invoke that verb,  <programmer> is
the player with whose permissions that verb is running, <verb-loc> is the
object on which that verb is defined, and <player> is the initial value of
the variable `player' in that verb.

The first element of the list returned by `callers()' gives information on
the verb that called the currently-executing verb, the second element describes
the verb that called that one, and so on.  The last element of the list
describes the first verb called in this task.


children()

Syntax:  parent (obj <object>)   => obj
       children (obj <object>)   => list

These functions return the parent and a list of the children of <object>,
respectively.  If <object> is not valid, then `E_INVARG' is returned.


chparent()

Syntax:  chparent () (obj <object>, obj <new-parent>)   => none

Changes the parent of <object> to be <new-parent>.  The programmer must
have read permission on <new-parent>; otherwise, `E_PERM' is returned.

Changing an object's parent can have the effect of removing some properties
from and adding some other properties to that object and all of its descendants
(i.e., its children and its children's children, etc.).  Let <common> be
the nearest ancestor that <object> and <new-parent> have in common
before the parent of <object> is changed.  Then all properties defined by
ancestors of <object> under <common> (that is, those ancestors of
<object> that are in turn descendants of <common>) are removed from
<object> and all of its descendants.  All properties defined by
<new-parent> or its ancestors under <common> are added to <object>
and all of its descendants.  As with `create()', the newly-added
properties are initialized with the same value and permission bits as they have
on <new-parent> and the owner of each added property is either the owner of
the object it's added to (if the `c' permissions bit is set) or the owner
of that property on <new-parent>.  All properties that are not removed or
added in the reparenting process are completely unchanged.


clear_property()

Syntax:  clear_property (obj <object>, str <prop-name>)  => none
      is_clear_property (obj <object>, str <prop-name>)  => boolean

As of version 1.6.6 of the server, the inherited properties (i.e.,
those defined on some ancestor of the object in question) are no
longer initialized to have the same value as does the parent.
Instead, they are initialized to `clear' (as in transparent); reading
the value of a clear property returns the value of the same property
on the parent (and if that one's clear, then the parent's parent, and
so on).  Thus, the apparent value on the child will change if that on
the parent does.  Assigning to a clear property `unclears' it and it
behaves normally thereafter.  The new built-in functions
`clear_property(obj, pname)' and `is_clear_property(obj, pname)' can
be used to re-clear a property and to test whether or not a particular
property is clear.  More documentation to follow.


connected_players()

Syntax:  connected_players ()   => list

Returns a list of the object numbers of those player objects with
currently-active connections.


connected_seconds()

Syntax:  connected_seconds (obj <player>)   => num
              idle_seconds (obj <player>)   => num

These functions return the number of seconds that the currently-active
connection to <player> has existed and been idle, respectively.  If
<player> is not the object number of a player object with a
currently-active connection, then `E_INVARG' is returned.


connection_name()

Syntax:  connection_name (obj <player>)   => str

Returns a network-specific string identifying the connection being used by the
given player.  If the programmer is not a wizard and not <player>, then
`E_PERM' is returned.  If <player> is not currently connected, then
`E_INVARG' is returned.

For the BSD UNIX network implementation (the only publicly-available one as of
this writing), the string has the form

    "<number> from <host>"

where <number> is a remarkably uninteresting internal server index and
<host> is either the name or decimal TCP address of the host from which the
player is connected.


create()

Syntax:  create (obj <parent> [, obj <owner>])   => obj

Creates and returns a new object whose parent is <parent> and whose owner
is as described below.  The given <parent> object must be readable by the
programmer (that is, either the programmer must own <parent>, or the
programmer must be a wizard, or the `r' permissions bit on the object must
be true); otherwise `E_PERM' is returned.  `E_PERM' is also returned
if <owner> is provided and not the same as the programmer, unless the
programmer is a wizard.  After the new object is created, its `initialize'
verb, if any, is called with no arguments.

The new object is assigned the least non-negative object number that has not
yet been used for a created object.  Note that no object number is ever reused,
even if the object with that number is recycled.

The owner of the new object is either the programmer (if <owner> is not
provided), the new object itself (if <owner> was given as `#-1'), or
<owner> (otherwise).

The other built-in properties of the new object are initialized as follows:
    name         ""
    location     #-1
    contents     {}
    programmer   0
    wizard       0
    r            0
    w            0

In addition, the new object inherits all of the other properties on
<parent>.  These properties have the same permission bits and value as on
<parent>.  If the `c' permissions bit is set, then the owner of the
property on the new object is the same as the owner of the new object itself;
otherwise, the owner of the property on the new object is the same as that on
<parent>.

If the intended owner of the new object has a property named
`ownership_quota' and the value of that property is a number, then
`create()' treats that value as a "quota".  If the quota is less than
or equal to zero, then the quota is considered to be exhausted and
`create()' returns `E_QUOTA' instead of creating an object.
Otherwise, the quota is decremented and stored back into the
`ownership_quota' property as a part of the creation of the new object.


crypt()

Syntax:  crypt (str <text> [, str <salt>])   => str

Encrypts the given <text> using the standard UNIX encryption method.  If
provided, <salt> should be a two-character string for use as the extra
encryption ``salt'' in the algorithm.  If <salt> is not provided, a random
pair of characters is used.  In any case, the salt used is also returned as the
first two characters of the resulting encrypted string.

Aside from the possibly-random selection of the salt, the encryption algorithm
is entirely deterministic.  In particular, you can test whether or not a given
string is the same as the one used to produced a given piece of encrypted text;
simply extract the first two characters of the encrypted text and pass the
candidate string and those two characters to `crypt()'.  If the result is
identical to the given encrypted text, then you've got a match.

    crypt("foobar")         =>   "J3fSFQfgkp26w"
    crypt("foobar", "J3")   =>   "J3fSFQfgkp26w"
    crypt("mumble", "J3")   =>   "J3D0.dh.jjmWQ"
    crypt("foobar", "J4")   =>   "J4AcPxOJ4ncq2"


ctime()

Syntax:  ctime ([num <time>])   => str

Interprets <time> as a time, using the same representation as given in the
description of `time()', and converts it into a 28-character,
human-readable string in the following format:

    Mon Aug 13 19:13:20 1990 PDT

If the current day of the month is less than 10, then an extra blank appears
between the month and the day:

    Mon Apr  1 14:10:43 1991 PST

If <time> is not provided, then the current time is used.

Note that `ctime()' interprets <time> for the local time zone of the
computer on which the MOO server is running.


delete_property()

Syntax:  delete_property (obj <object>, str <prop-name>)   => none

Removes the property named <prop-name> from the given <object> and all
of its descendants.  If <object> is not valid, then `E_INVARG' is
returned.  If the programmer does not have write permission on <object>,
then `E_PERM' is returned.  If <object> does not directly define a
property named <prop-name> (as opposed to inheriting one from its parent),
then `E_PROPNF' is returned.


delete_verb()

Syntax:  delete_verb (obj <object>, str <verb-name>)   => none

Removes the verb named <verb-name> from the given <object>.  If
<object> is not valid, then `E_INVARG' is returned.  If the programmer
does not have write permission on <object>, then `E_PERM' is returned.
If <object> does not define a verb named <verb-name>, then
`E_VERBNF' is returned.


dump_database()

Syntax:  dump_database ()   => none

Requests that the server checkpoint the database at its next opportunity.  It
is not normally necessary to call this function; the server automatically
checkpoints the database at regular intervals; see the chapter on server
assumptions about the database for details.  If the programmer is not a wizard,
then `E_PERM' is returned.


eval()

Syntax:  eval (str <string>)   => list

The MOO-code compiler processes <string> as if it were to be the program
associated with some verb and, if no errors are found, that fictional verb is
invoked.  If the programmer is not, in fact, a programmer, then `E_PERM'
is returned.  The normal result of calling `eval()' is a two element list.
The first element is true if there were no compilation errors and false
otherwise.  The second element is either the result returned from the fictional
verb (if there were no compilation errors) or a list of the compiler's error
messages (otherwise).

When the fictional verb is invoked, the various built-in variables have values
as shown below:

    player    the same as in the calling verb
    this      #-1
    caller    the same as the initial value of `this' in the calling verb

    args      {}
    argstr    ""

    verb      ""
    dobjstr   ""
    dobj      #-1
    prepstr   ""
    iobjstr   ""
    iobj      #-1

The fictional verb runs with the permissions of the programmer and as if its
`d' permissions bit were on.

    eval("return 3 + 4;")   =>   {1, 7}


idle_seconds()

Syntax:  connected_seconds (obj <player>)   => num
              idle_seconds (obj <player>)   => num

These functions return the number of seconds that the currently-active
connection to <player> has existed and been idle, respectively.  If
<player> is not the object number of a player object with a
currently-active connection, then `E_INVARG' is returned.


index()

Syntax:  index (str <str1>, str <str2> [, <case-matters>])   => num
        rindex (str <str1>, str <str2> [, <case-matters>])   => num

The function `index()' (`rindex()') returns the index of the first
character of the first (last) occurrence of <str2> in <str1>, or zero
if <str2> does not occur in <str1> at all.  By default the search for
an occurrence of <str2> is done while ignoring the upper/lower case
distinction.  If <case-matters> is provided and true, then case is treated
as significant in all comparisons.

    index("foobar", "o")        =>   2
    rindex("foobar", "o")       =>   3
    index("foobar", "x")        =>   0
    index("foobar", "oba")      =>   3
    index("Foobar", "foo", 1)   =>   0


is_clear_property()

Syntax:  clear_property (obj <object>, str <prop-name>)  => none
      is_clear_property (obj <object>, str <prop-name>)  => boolean

As of version 1.6.6 of the server, the inherited properties (i.e.,
those defined on some ancestor of the object in question) are no
longer initialized to have the same value as does the parent.
Instead, they are initialized to `clear' (as in transparent); reading
the value of a clear property returns the value of the same property
on the parent (and if that one's clear, then the parent's parent, and
so on).  Thus, the apparent value on the child will change if that on
the parent does.  Assigning to a clear property `unclears' it and it
behaves normally thereafter.  The new built-in functions
`clear_property(obj, pname)' and `is_clear_property(obj, pname)' can
be used to re-clear a property and to test whether or not a particular
property is clear.  More documentation to follow.


is_player()

Syntax:  is_player (obj <object>)   => num

Returns a true value if the given <object> is a player object and a false
value otherwise.  If <object> is not valid, `E_INVARG' is returned.


kill_task()

Syntax:  kill_task (num <task-id>)   => none

Removes the task with the given <task-id> from the queue of waiting tasks.
If the programmer is not the owner of that task and not a wizard, then
`E_PERM' is returned.  If there is no task on the queue with the given
<task-id>, then `E_INVARG' is returned.


length()

Syntax:  length (<list or string>)   => num

Returns the number of characters in <list or string>.  

    length("foo")       =>   3
    length("")          =>   0
    length({1, 2, 3})   =>   3
    length({})          =>   0


listappend()

Syntax:  listinsert (list <list>, <value> [, num <index>])   => list
         listappend (list <list>, <value> [, num <index>])   => list

These functions return a copy of <list> with <value> added as a new
element.  `listinsert()' and `listappend()' add <value> before
and after (respectively) the existing element with the given <index>, if
provided.

The following three expressions always have the same value:

    listinsert(<list>, <element>, <index>)
    listappend(<list>, <element>, <index> - 1)
    {@<list>[1..<index> - 1], <element>, @<list>[<index>..length(<list>)]}

If <index> is not provided, then `listappend()' adds the <value>
at the end of the list and `listinsert()' adds it at the beginning; this
usage is discouraged, however, since the same intent can be more clearly
expressed using the list-construction expression, as shown in the examples
below.

    x = {1, 2, 3};
    listappend(x, 4, 2)   =>   {1, 2, 4, 3}
    listinsert(x, 4, 2)   =>   {1, 4, 2, 3}
    listappend(x, 4)      =>   {1, 2, 3, 4}
    listinsert(x, 4)      =>   {4, 1, 2, 3}
    {@x, 4}               =>   {1, 2, 3, 4}
    {4, @x}               =>   {4, 1, 2, 3}


listdelete()

Syntax:  listdelete (list <list>, num <index>)   => list

Returns a copy of <list> with the <index>th element removed.  If
<index> is not in the range `[1..length(<list>)]', then
`E_RANGE' is returned.

    x = {"foo", "bar", "baz"};
    listdelete(x, 2)   =>   {"foo", "baz"}


listen()

Syntax:  listen (obj <listener>, num <port>)   => none

Tells the server to start listening on <port>, and to attach
incoming connections on that port to <listener>.  The programmer
must be a wizard, or `E_PERM` is returned.  If the object is not
valid, `E_INVARG' is returned; if the server cannot open a socket on
the given port, `E_VARNF' is returned.

When a connection is made to the given port,
<listener>:do_login_command is called with no arguments and with
`player' set to a negative object number.  Subsequent commands from
the connection will be sent to :do_login_command, with `args' equal to
a list of the words in the command.  If :do_login_command returns a
player object, the connection will be logged in as that object, and
commands from the connection will be handled in the normal way.

Note that this makes the standard login port exactly equivalent to the
result of a call `listen(#0, <port>)'.

See `help $network:listen'[1] for possible non-wizardly access to the
listen() function.


listinsert()

Syntax:  listinsert (list <list>, <value> [, num <index>])   => list
         listappend (list <list>, <value> [, num <index>])   => list

These functions return a copy of <list> with <value> added as a new
element.  `listinsert()' and `listappend()' add <value> before
and after (respectively) the existing element with the given <index>, if
provided.

The following three expressions always have the same value:

    listinsert(<list>, <element>, <index>)
    listappend(<list>, <element>, <index> - 1)
    {@<list>[1..<index> - 1], <element>, @<list>[<index>..length(<list>)]}

If <index> is not provided, then `listappend()' adds the <value>
at the end of the list and `listinsert()' adds it at the beginning; this
usage is discouraged, however, since the same intent can be more clearly
expressed using the list-construction expression, as shown in the examples
below.

    x = {1, 2, 3};
    listappend(x, 4, 2)   =>   {1, 2, 4, 3}
    listinsert(x, 4, 2)   =>   {1, 4, 2, 3}
    listappend(x, 4)      =>   {1, 2, 3, 4}
    listinsert(x, 4)      =>   {4, 1, 2, 3}
    {@x, 4}               =>   {1, 2, 3, 4}
    {4, @x}               =>   {4, 1, 2, 3}


listset()

Syntax:  listset (list <list>, <value>, num <index>)   => list

Returns a copy of <list> with the <index>th element replaced by
<value>.  If <index> is not in the range
`[1..length(<list>)]', then `E_RANGE' is returned.

    x = {"foo", "bar", "baz"};
    listset(x, "mumble", 2)   =>   {"foo", "mumble", "baz"}


match()

Syntax:  match (str <subject>, str <pattern> [, <case-matters>])  => list
         rmatch (str <subject>, str <pattern> [, <case-matters>])  => list

The function `match()' (`rmatch()') searches for the first (last)
occurrence of the regular expression <pattern> in the string
<subject>.  If <pattern> is syntactically malformed, then
`E_INVARG' is returned.  If no match is found, the empty list is
returned; otherwise, these functions return a list containing
information about the match (see below).  By default, the search
ignores upper/lower case distinctions.  If <case-matters> is
provided and true, then case is treated as significant in all
comparisons.

The list that `match()' (`rmatch()') returns contains the details
about the match made.  The list is in the form:

     {<start>, <end>, <replacements>, <subject>}

where <start> is the index in STRING of the beginning of the
match, <end> is the index of the end of the match,
<replacements> is a list described below, and <subject> is
the same string that was given as the first argument to the `match()'
or `rmatch()'.

The <replacements> list is always nine items long, each item
itself being a list of two numbers, the start and end indices in
<subject> matched by some parenthesized sub-pattern of
<pattern>.  The first item in <replacements> carries the
indices for the first parenthesized sub-pattern, the second item
carries those for the second sub-pattern, and so on.  If there are
fewer than nine parenthesized sub-patterns in <pattern>, or if
some sub-pattern was not used in the match, then the corresponding
item in <replacements> is the list {0, -1}.  See the discussion
of `%)' in `help regular-expressions', for more information on
parenthesized sub-patterns.

   match("foo", "f*o")          =>  {1, 2, {{0, -1}, ...}, "foo"}
   match("foo", "fo*")          =>  {1, 3, {{0, -1}, ...}, "foo"}
   match("foobar", "o*b")       =>  {2, 4, {{0, -1}, ...}, "foobar"}
   rmatch("foobar", "o*b")      =>  {4, 4, {{0, -1}, ...}, "foobar"}
   match("foobar", "f%(o*%)b")  =>  {1, 4, {{2, 3}, {0, -1}, ...}, "foobar"}

See `help regular-expressions'[1] for information on the syntax and semantics of patterns.


max()

Syntax:  min (num <x>, ...)   => num
         max (num <x>, ...)   => num

These two functions return the smallest or largest of their arguments,
respectively.  All of the arguments must be numbers; otherwise `E_TYPE' is
returned.


max_object()

Syntax:  max_object ()   => obj

Returns the largest object number yet assigned to a created object.  Note that
the object with this number may no longer exist; it may have been recycled.
The next object created will be assigned the object number one larger than the
value of `max_object()'.


memory_usage()

Syntax:  memory_usage ()   => list

On some versions of the server, this returns statistics concerning the server
consumption of system memory.  The result is a list of lists, each in the
following format:

    {<block-size>, <nused>, <nfree>}

where <block-size> is the size in bytes of a particular class of memory
fragments, <nused> is the number of such fragments currently in use in the
server, and <nfree> is the number of such fragments that have been reserved
for use but are currently free.

On servers for which such statistics are not available, `memory_usage()'
returns `{}'.  The compilation option `USE_SYSTEM_MALLOC' controls
whether or not statistics are available; if the option is provided, statistics
are not available.


min()

Syntax:  min (num <x>, ...)   => num
         max (num <x>, ...)   => num

These two functions return the smallest or largest of their arguments,
respectively.  All of the arguments must be numbers; otherwise `E_TYPE' is
returned.


move()

Syntax:  move (obj <what>, obj <where>)   => none

Changes <what>'s location to be <where>.  This is a complex process
because a number of permissions checks and notifications must be performed.
The actual movement takes place as described in the following paragraphs.

<what> should be a valid object and <where> should be either a valid
object or `#-1' (denoting a location of 'nowhere'); otherwise
`E_INVARG' is returned.  The programmer must be either the owner of
<what> or a wizard; otherwise, `E_PERM' is returned.

If <where> is a valid object, then the verb-call

    <where>:accept(<what>)

is performed before any movement takes place.  If the verb returns a
false value and the programmer is not a wizard, then <where> is
considered to have refused entrance to <what>; `move()' returns
`E_NACC'.  If <where> does not define an `accept' verb, then it
is treated as if it defined one that always returned false.

If moving <what> into <where> would create a loop in the containment
hierarchy (i.e., <what> would contain itself, even indirectly), then
`E_RECMOVE' is returned instead.

The `location' property of <what> is changed to be <where>, and
the `contents' properties of the old and new locations are modified
appropriately.  Let <old-where> be the location of <what> before it was
moved.  If <old-where> is a valid object, then the verb-call

    <old-where>:exitfunc(<what>)

is performed and its result is ignored; it is not an error if <old-where>
does not define a verb named `exitfunc'.  Finally, if <where> and
<what> are still valid objects, and <where> is still the location of
<what>, then the verb-call

    <where>:enterfunc(<what>)

is performed and its result is ignored; again, it is not an error if
<where> does not define a verb named `enterfunc'.


notify()

Syntax:  notify (obj <player>, str <string>)   => none

Outputs <string> (on a line by itself) to the user connected to the given
<player>.  If the programmer is not <player> or a wizard, then
`E_PERM' is returned.  If there is no currently-active connection to
<player>, then this function does nothing.


open_network_connection()

Syntax:  open_network_connection (<value>, ...)   => obj

Establishes a network connection to the place specified by the arguments and
pretends that a new, normal player connection has been established from there.
The new connection, as usual, will not be logged in initially and will have a
negative object number associated with it for use with `read()',
`notify()', and `boot_player()'.  This object number is the value returned by this function.

If the programmer is not a wizard or if the `OUTBOUND_NETWORK' compilation
option was not used in building the server, then `E_PERM' is returned.  If
the network connection cannot be made for some reason, then other errors will
be returned, depending upon the particular network implementation in use.

For the BSD UNIX network implementation (the only publicly-available one as of
this writing), there must be two arguments, a string naming a host (possibly
using the numeric Internet syntax) and a number specifying a TCP port.  If a
connection cannot be made because the host does not exist, the port does not
exist, the host is not reachable or refused the connection, `E_INVARG' is
returned.  If the connection cannot be made for other reasons, including
resource limitations, then `E_QUOTA' is returned.

It is worth mentioning a couple of tricky points concerning the use of this
function.

Since the server treats the new connection like any other normal
player connection, it will naturally try to parse any input from that
connection as commands in the usual way.  To prevent this treatment, it is
necessary to ensure that some task is always suspended using `read()' on
the connection whenever the server considers a line of input from it.  That
way, the line of input will be given to that task instead of being parsed as a
command.  The only reliable way to ensure this is for the task that opens the
connection to enter an infinite loop reading from the connection.  One possible
structure for such a task is as follows:

    conn = open_network_connection(...);
    read(conn);
    while (1)
      line = read(conn);
      fork (0)
        this:handle_input(line);
      endfork
    endwhile

The first call to `read()' in this example is to discard the null line of
input always automatically supplied by the server for new connections; for more
details, see the discussion of `#0:do_login_command' in the section on
server commands and database assumptions.

The second fine point to be considered is that, unless the new connection
eventually `logs in' in the usual way for players, the server will impose its
usual five-minute timeout on it, shutting down the connection unless new input
arrives at least once every five minutes.


output_delimiters()

Syntax:  output_delimiters (obj <player>)   => list

Returns a list of two strings, the current "output prefix" and "output
suffix" for <player>.  If <player> does not have an active network
connection, then `E_INVARG' is returned.  If either string is currently
undefined, the value `""' is used instead.  See the discussion of the
`PREFIX' and `SUFFIX' commands in the next chapter for more
information about the output prefix and suffix.


parent()

Syntax:  parent (obj <object>)   => obj
       children (obj <object>)   => list

These functions return the parent and a list of the children of <object>,
respectively.  If <object> is not valid, then `E_INVARG' is returned.


pass()

Syntax:  pass (<arg>,...)

Often, it is useful for a child object to define a verb that *augments*
the behavior of a verb on its parent object.  For example, the root object 
(an ancestor of every other object) defines a :description() verb that 
simply returns the value of `this.description'; 
this verb is used by the implementation of the `look' command.  
In many cases, a programmer would like the description of some object to
include some non-constant part; for example, a sentence about whether or not
the object was `awake' or `sleeping'.  This sentence should be added onto the
end of the normal description.  The programmer would like to have a means of
calling the normal `description' verb and then appending the sentence onto the
end of that description.  The function `pass()' is for exactly such situations.

pass() calls the verb with the same name as the current verb but as
defined on the parent of the object that defines the current verb.  The
arguments given to the called verb are the ones given to pass() and the
returned value of the called verb is returned from the call to pass().
The initial value of `this' in the called verb is the same as in the
calling verb.

Thus, in the example above, the child-object's :description() verb might
have the following implementation:

    return pass(@args) + "  It is " + (this.awake ? "awake." | "sleeping.");

That is, it calls its parent's :description() verb and then appends to the
result a sentence whose content is computed based on the value of a property on
the object.

In the above example, `pass()' would have worked just as well, since
:description() is not normally given any arguements.  However, it is a
good idea to get into the habit of using `pass(@args)' rather than
`pass(args[1])' or `pass()' even if the verb being pass()ed to is
already known to take a set number of arguments or none at all.  For
one thing, though the args may be irrelevant to the code that you've
written, it may be that the corresponding verb on the parent has been
rewritten to take additional arguments, in which case you will want
your verb to continue to work...


players()

Syntax:  players ()   => list

Returns a list of the object numbers of all player objects in the database.


properties()

Syntax:  properties (obj <object>)   => list

Returns a list of the names of the properties defined directly on the given
<object>, not inherited from its parent.  If <object> is not valid,
then `E_INVARG' is returned.  If the programmer does not have read
permission on <object>, then `E_PERM' is returned.


property_info()

Syntax:  property_info (obj <object>, str <prop-name>)   => list
     set_property_info (obj <object>, str <prop-name>, list <info>)   => none

These two functions get and set (respectively) the owner and permission bits
for the property named <prop-name> on the given <object>.  If
<object> is not valid, then `E_INVARG' is returned.  If <object>
has no non-built-in property named <prop-name>, then `E_PROPNF' is
returned.  If the programmer does not have read (write) permission on the
property in question, then `property_info()' (`set_property_info()')
returns `E_PERM'.  Property info has the following form:

    {<owner>, <perms>}

where <owner> is an object and <perms> is a string containing only
characters from the set `r', `w', and `c'.  This is the kind of
value returned by `property_info()' and expected as the third argument to
`set_property_info()'; the latter function returns `E_INVARG' if
<owner> is not valid or <perms> contains any illegal characters.


queued_tasks()

Syntax:  queued_tasks ()   => list

Returns information on each of the forked, suspended or reading tasks owned by
the programmer (or, if the programmer is a wizard, all queued tasks).  The
returned value is a list of lists, each of which encodes certain information
about a particular queued task in the following format:

    {<task-id>, <start-time>, <ticks>, <clock-id>,
     <programmer>, <verb-loc>, <verb-name>, <line>, <this>}

where <task-id> is a numeric identifier for this queued task,
<start-time> is the time after which this task will begin execution (in
`time()' format), <ticks> is the number of ticks this task will have
when it starts (always 20,000 now), <clock-id> is a number whose value is
no longer interesting, <programmer> is the permissions with which this task
will begin execution (and also the player who "owns" this task),
<verb-loc> is the object on which the verb that forked this task was
defined at the time, <verb-name> is that name of that verb, <line> is
the number of the first line of the code in that verb that this task will
execute, and <this> is the value of the variable `this' in that verb.
For reading tasks, <start-time> is `-1'.

The <ticks> and <clock-id> fields are now obsolete and are retained
only for backward-compatibility reasons.  They may disappear in a future
version of the server.


random()

Syntax:  random (num <mod>)   => num

<mod> must be a positive number; otherwise, `E_INVARG' is returned.  A
number is chosen randomly from the range `[1..<mod>]' and returned.


read()

Syntax:  read ([obj <player>])   => str

This function suspends the current task, waiting for a line of input from the
given <player> (which defaults to the player that typed the command that
initiated the current task), and resumes when such a line is received,
returning that line as a string.  Upon resumption, the task is given a full
quota of ticks and seconds.  `Read()' may only be called by a wizard, and,
unless <player> is given explicitly, only in a command task that has never
been suspended by a call to `suspend()'.  Otherwise, `E_PERM' is
returned.  If the given `player' is not currently connected and has no
pending lines of input, `read()' returns `E_INVARG'.

These restrictions on the use of `read()' without an explicit argument
preserve the following simple invariant: if input is being read from a player,
it is for the task started by the last command that player typed.  This
invariant adds responsibility to the programmer, however.  If your program
calls another verb before doing a `read()', then that verb must also not
suspend.  As an example, consider the following, which refers to the verbs
programmed in the `suspend()' example in `help suspend()':

    .program   #0:read_twice_A
    s = read();        /* success depends on programmer's permissions */
    #0:callee_A();     /* callee_A does not suspend */
    t = read();        /* success depends on programmer's permissions */
    .

    .program   #0:read_twice_B
    s = read();        /* success depends on programmer's permissions */
    #0:callee_B();     /* callee_B does suspend */
    t = read();        /* fails, returning E_PERM */
    .

In three of the four calls to `read()', success depends on on the
programmer's permissions.  However, the second `read()' in
`#0:read_twice_B' always fails and returns `E_PERM'.  This is because
the task was suspended, even though `#0:read_twice_B' did not do the
actual suspending.  Hence, if you want to read some input (by using
`read()' directly or by calling other verbs which do the reading), you
must make sure that the task is not suspended before the reading.  This
includes making sure that any verbs you call, directly or indirectly, also do
not suspend.

It is possible to call `read()' many times in the same command task, so
long as the task does not call `suspend()' or an explicit argument is
given.  The best use for `read()' with an explicit argument is in
conjunction with `open_network_connection()', if it is enabled.


recycle()

Syntax:  recycle (obj <object>)   => none

The given <object> is destroyed, irrevocably.  The programmer must either
own <object> or be a wizard; otherwise, `E_PERM' is returned.  If
<object> is not valid, then `E_INVARG' is returned.  The children of
<object> are reparented to the parent of <object>.  Before <object>
is recycled, each object in its contents is moved to `#-1' (implying a
call to <object>'s `exitfunc' verb, if any) and then <object>'s
`recycle' verb, if any, is called with no arguments.

After <object> is recycled, if the owner of the former object has a
property named `ownership_quota' and the value of that property is a
number, then `recycle()' treats that value as a "quota" and increments
it by one, storing the result back into the `ownership_quota' property.


renumber()

Syntax:  renumber (obj <object>)   => obj

The object number of the object currently numbered <object> is changed to
be the least nonnegative object number not currently in use and the new object
number is returned.  If <object> is not valid, then `E_INVARG' is
returned.  If the programmer is not a wizard, then `E_PERM' is returned.
If there are no unused nonnegative object numbers less than <object>, then
<object> is returned and no changes take place.

The references to <object> in the parent/children and location/contents
hierarchies are updated to use the new object number, and any verbs, properties
and/or objects owned by <object> are also changed to be owned by the new
object number.  The latter operation can be quite time consuming if the
database is large.  No other changes to the database are performed; in
particular, no object references in property values or verb code are updated.

This operation is intended for use in making new versions of the LambdaCore
database from the then-current LambdaMOO database, and other similar
situations.  Its use requires great care.


reset_max_object()

Syntax:  reset_max_object ()   => none

The server's idea of the highest object number ever used is changed to be the
highest object number of a currently-existing object, thus allowing reuse of
any higher numbers that refer to now-recycled objects.  If the programmer is
not a wizard, then `E_PERM' is returned.

This operation is intended for use in making new versions of the LambdaCore
database from the then-current LambdaMOO database, and other similar
situations.  Its use requires great care.


rindex()

Syntax:  index (str <str1>, str <str2> [, <case-matters>])   => num
        rindex (str <str1>, str <str2> [, <case-matters>])   => num

The function `index()' (`rindex()') returns the index of the first
character of the first (last) occurrence of <str2> in <str1>, or zero
if <str2> does not occur in <str1> at all.  By default the search for
an occurrence of <str2> is done while ignoring the upper/lower case
distinction.  If <case-matters> is provided and true, then case is treated
as significant in all comparisons.

    index("foobar", "o")        =>   2
    rindex("foobar", "o")       =>   3
    index("foobar", "x")        =>   0
    index("foobar", "oba")      =>   3
    index("Foobar", "foo", 1)   =>   0


rmatch()

Syntax:  match (str <subject>, str <pattern> [, <case-matters>])  => list
         rmatch (str <subject>, str <pattern> [, <case-matters>])  => list

The function `match()' (`rmatch()') searches for the first (last)
occurrence of the regular expression <pattern> in the string
<subject>.  If <pattern> is syntactically malformed, then
`E_INVARG' is returned.  If no match is found, the empty list is
returned; otherwise, these functions return a list containing
information about the match (see below).  By default, the search
ignores upper/lower case distinctions.  If <case-matters> is
provided and true, then case is treated as significant in all
comparisons.

The list that `match()' (`rmatch()') returns contains the details
about the match made.  The list is in the form:

     {<start>, <end>, <replacements>, <subject>}

where <start> is the index in STRING of the beginning of the
match, <end> is the index of the end of the match,
<replacements> is a list described below, and <subject> is
the same string that was given as the first argument to the `match()'
or `rmatch()'.

The <replacements> list is always nine items long, each item
itself being a list of two numbers, the start and end indices in
<subject> matched by some parenthesized sub-pattern of
<pattern>.  The first item in <replacements> carries the
indices for the first parenthesized sub-pattern, the second item
carries those for the second sub-pattern, and so on.  If there are
fewer than nine parenthesized sub-patterns in <pattern>, or if
some sub-pattern was not used in the match, then the corresponding
item in <replacements> is the list {0, -1}.  See the discussion
of `%)' in `help regular-expressions', for more information on
parenthesized sub-patterns.

   match("foo", "f*o")          =>  {1, 2, {{0, -1}, ...}, "foo"}
   match("foo", "fo*")          =>  {1, 3, {{0, -1}, ...}, "foo"}
   match("foobar", "o*b")       =>  {2, 4, {{0, -1}, ...}, "foobar"}
   rmatch("foobar", "o*b")      =>  {4, 4, {{0, -1}, ...}, "foobar"}
   match("foobar", "f%(o*%)b")  =>  {1, 4, {{2, 3}, {0, -1}, ...}, "foobar"}

See `help regular-expressions'[1] for information on the syntax and semantics of patterns.


seconds_left()

Syntax:  ticks_left ()   => num
       seconds_left ()   => num

These two functions return the number of ticks or seconds (respectively) left
to the current task before it will be forcibly terminated.  These are useful,
for example, in deciding when to fork another task to continue a long-lived
computation.


server_log()

Syntax:  server_log (str <message> [, <is-error>])  => none

The text in <message> is sent to the server log.  If the
programmer is not a wizard, then `E_PERM' is returned.  If
<is-error> is provided and true, then <message> is marked
in the server log as an error.


server_version()

Syntax:  server_version ()   => str

Returns a string giving the version number of the MOO server in the following
format:

    "<major>.<minor>.<release>"

where <major>, <minor>, and <release> are all decimal numbers.

The major version number changes very slowly, only when existing MOO code might
stop working, due to an incompatible change in the syntax or semantics of the
programming language, or when an incompatible change is made to the database
format.

The minor version number changes more quickly, whenever an upward-compatible
change is made in the programming language syntax or semantics.  The most
common cause of this is the addition of a new kind of expression, statement, or
built-in function.

The release version number changes as frequently as bugs are fixed in the
server code.  Changes in the release number indicate changes that should only
be visible to users as bug fixes, if at all.


set_player_flag()

Syntax:  set_player_flag (obj <object>, <value>)   => none

Confers or removes the ``player object'' status of the given <object>,
depending upon the truth value of <value>.  If <object> is not valid,
`E_INVARG' is returned.  If the programmer is not a wizard, then
`E_PERM' is returned.

If <value> is true, then <object> gains (or keeps) ``player object''
status: it will be an element of the list returned by `players()', the
expression `is_player(<object>)' will return true, and users can
connect to <object> by name when they log into the server.

If <value> is false, the <object> loses (or continues to lack) ``player
object'' status: it will not be an element of the list returned by
`players()', the expression `is_player(<object>)' will return
false, and users cannot connect to <object> by name when they log into the
server.  In addition, if a user is connected to <object> at the time that
it loses ``player object'' status, then that connection is immediately broken,
just as if `boot_player(<object>)' had been called (see the
description of `boot_player()' below).


set_property_info()

Syntax:  property_info (obj <object>, str <prop-name>)   => list
     set_property_info (obj <object>, str <prop-name>, list <info>)   => none

These two functions get and set (respectively) the owner and permission bits
for the property named <prop-name> on the given <object>.  If
<object> is not valid, then `E_INVARG' is returned.  If <object>
has no non-built-in property named <prop-name>, then `E_PROPNF' is
returned.  If the programmer does not have read (write) permission on the
property in question, then `property_info()' (`set_property_info()')
returns `E_PERM'.  Property info has the following form:

    {<owner>, <perms>}

where <owner> is an object and <perms> is a string containing only
characters from the set `r', `w', and `c'.  This is the kind of
value returned by `property_info()' and expected as the third argument to
`set_property_info()'; the latter function returns `E_INVARG' if
<owner> is not valid or <perms> contains any illegal characters.


set_task_perms()

Syntax:  set_task_perms (obj <player>)   => none

Changes the permissions with which the currently-executing verb is running to
be those of <player>.  If <player> is not a valid player object, then
`E_INVARG' is returned.  If the programmer is neither <player> nor a
wizard, then `E_PERM' is returned.

Note: This does not change the owner of the currently-running verb, only the
permissions of this particular invocation.  It is used in verbs owned by
wizards to make themselves run with lesser (usually non-wizard) permissions.


set_verb_args()

Syntax:  verb_args (obj <object>, str <verb-name>)   => list
     set_verb_args (obj <object>, str <verb-name>, list <args>)   => none

These two functions get and set (respectively) the direct-object,
preposition, and indirect-object specifications for the verb named
<verb-name> on the given <object>.  If <object> is
not valid, then `E_INVARG' is returned.  If <object> does not
define a verb named <verb-name>, then `E_VERBNF' is returned.
If the programmer does not have read (write) permission on the verb in
question, then `verb_args()' (`set_verb_args()') returns `E_PERM'.
Verb args specifications have the following form:

    {<dobj>, <prep>, <iobj>}

where <dobj> and <iobj> are strings drawn from the set
`"this"', `"none"', and `"any"', and <prep> is a string that is
either `"none"', `"any"', or one of the prepositional phrases listed
much earlier in the description of verbs in the first chapter.  This
is the kind of value returned by `verb_info()' and expected as the
third argument to `set_verb_info()'.  Note that for `set_verb_args()',
<prep> must be only one of the prepositional phrases, not (as is
shown in that table) a set of such phrases separated by `/'
characters.  `Set_verb_args()' returns `E_INVARG' if any of the
<dobj>, <prep>, or <iobj> strings is illegal.

    verb_args($container, "take")
                        =>   {"any", "out of/from inside/from", "this"}
    set_verb_args($container, "take", {"any", "from", "this"})


set_verb_code()

Syntax:  verb_code (obj <object>, str <verb-name> [, <fully-paren> [, <indent>]])   => list
     set_verb_code (obj <object>, str <verb-name>, list <code>)   => list

These functions get and set (respectively) the MOO-code program
associated with the verb named <verb-name> on <object>.
The program is represented as a list of strings, one for each line of
the program; this is the kind of value returned by `verb_code()' and
expected as the third argument to `set_verb_code()'.  For
`verb_code()', the expressions in the returned code are usually
written with the minimum-necessary parenthesization; if
<full-paren> is true, then all expressions are fully
parenthesized.  Also for `verb_code()', the lines in the returned code
are usually not indented at all; if <indent> is true, each line
is indented to better show the nesting of statements.

If <object> is not valid, then `E_INVARG' is returned.  If
<object> does not define a verb named <verb-name>, then
`E_VERBNF' is returned.  If the programmer does not have read (write)
permission on the verb in question, then `verb_code()'
(`set_verb_code()') returns `E_PERM'.  If the programmer is not, in
fact. a programmer, then `E_PERM' is returned.

For `set_verb_code()', the result is a list of strings, the error
messages generated by the MOO-code compiler during processing of
<code>.  If the list is non-empty, then `set_verb_code()' did
not install <code>; the program associated with the verb in
question is unchanged.


set_verb_info()

Syntax:  verb_info (obj <object>, str <verb-name>)   => list
     set_verb_info (obj <object>, str <verb-name>, list <info>)   => none

These two functions get and set (respectively) the owner, permission bits, and
name(s) for the verb named <verb-name> on the given <object>.  If
<object> is not valid, then `E_INVARG' is returned.  If <object>
does not define a verb named <verb-name>, then `E_VERBNF' is returned.
If the programmer does not have read (write) permission on the verb in
question, then `verb_info()' (`set_verb_info()') returns
`E_PERM'.  Verb info has the following form:

    {<owner>, <perms>, <names>}

where <owner> is an object, <perms> is a string containing only
characters from the set `r', `w', `x', and `d', and
<names> is a string.  This is the kind of value returned by
`verb_info()' and expected as the third argument to
`set_verb_info()'; the latter function returns `E_INVARG' if
<owner> is not valid or <perms> contains any illegal characters.


setadd(), setremove()

Syntax:  setadd (list <list>, <value>)   => list
      setremove (list <list>, <value>)   => list

Returns a copy of <list> with the given <value> added or removed, as
appropriate.  `setadd()' only adds <value> if it is not already an
element of <list>; <list> is thus treated as a mathematical set.
<value> is added at the end of the resulting list, if at all.  Similarly,
`setremove()' returns a list identical to <list> if <value> is not
an element.  If <value> appears more than once in <list>, only the
first occurrence is removed in the returned copy.

    setadd({1, 2, 3}, 3)         =>   {1, 2, 3}
    setadd({1, 2, 3}, 4)         =>   {1, 2, 3, 4}
    setremove({1, 2, 3}, 3)      =>   {1, 2}
    setremove({1, 2, 3}, 4)      =>   {1, 2, 3}
    setremove({1, 2, 3, 2}, 2)   =>   {1, 3, 2}


shutdown()

Syntax:  shutdown (str <message>)   => none

Requests that the server shut itself down at its next opportunity.  Before
doing so, the given <message> is printed to all connected players.  If the
programmer is not a wizard, then `E_PERM' is returned.


sqrt()

Syntax:  sqrt (num <x>)  => num

Returns the square root of <x>.  If <x> is negative, then `E_INVARG' is returned.


strcmp()

Syntax:  strcmp (str <str1>, str <str2>)   => num

Performs a case-sensitive comparison of the two argument strings.  If
<str1> is lexicographically less than <str2>, the
`strcmp()' returns a negative number.  If the two strings are
identical, `strcmp()' returns zero.  Otherwise, `strcmp()'
returns a positive number.  The ASCII character ordering is used for the
comparison.


strsub()

Syntax:  strsub (str <subject>, str <what>, str <with> [, <case-matters>])   => str

Replaces all occurrences in <subject> of <what> with <with>,
performing string substitution.  The occurrences are found from left to right
and all substitutions happen simultaneously.  By default, occurrences of
<what> are searched for while ignoring the upper/lower case distinction.
If <case-matters> is provided and true, then case is treated as significant
in all comparisons.

    strsub("%n is a fink.", "%n", "Fred")   =>   "Fred is a fink."
    strsub("foobar", "OB", "b")             =>   "fobar"
    strsub("foobar", "OB", "b", 1)          =>   "foobar"


substitute()

Syntax:  substitute (str <template>, list <subs>)  => str

Performs a standard set of substitutions on the string
<template>, using the information contained in <subs>,
returning the resulting, transformed <template>.  <Subs>
should be a list like those returned by `match()' or `rmatch()' when
the match succeeds.

In <template>, the strings `%1' through `%9' will be replaced by
the text matched by the first through ninth parenthesized sub-patterns
when `match()' or `rmatch()' was called.  The string `%0' in
<template> will be replaced by the text matched by the pattern
as a whole when `match()' or `rmatch()' was called.

     subs = match("*** Welcome to LambdaMOO!!!", "%(%w*%) to %(%w*%)");
     substitute("I thank you for your %1 here in %2.", subs)
             =>   "I thank you for your Welcome here in LambdaMOO."


suspend()

Syntax:  suspend (num <seconds>)   => none

Suspends the current task, and resumes it after at least <seconds> seconds.
When the task is resumed, it will have a full quota of ticks and seconds.  This
function is useful for programs that run for a long time or require a lot of
ticks.  If <seconds> is negative, then `E_INVARG' is returned.

In some sense, this function forks the `rest' of the executing task.  However,
there is a major difference between the use of `suspend(<seconds>)'
and the use of the `fork (<seconds>)'.  The `fork' statement
creates a new task (a "forked task") while the currently-running task still
goes on to completion, but a `suspend()' suspends the currently-running
task (thus making it into a "suspended task").  This difference may be best
explained by the following examples, in which one verb calls another:

    .program   #0:caller_A
    #0.prop = 1;
    #0:callee_A();
    #0.prop = 2;
    .

    .program   #0:callee_A
    fork(5)
      #0.prop = 3;
    endfork
    .

    .program   #0:caller_B
    #0.prop = 1;
    #0:callee_B();
    #0.prop = 2;
    .

    .program   #0:callee_B
    suspend(5);
    #0.prop = 3;
    .

Consider `#0:caller_A', which calls `#0:callee_A'.  Such a task would
assign 1 to `#0.prop', call `#0:callee_A', fork a new task, return to
`#0:caller_A', and assign 2 to `#0.prop', ending this task.  Five
seconds later, if the forked task had not been killed, then it would begin to
run; it would assign 3 to `#0.prop' and then stop.  So, the final value of
`#0.prop' (i.e., the value after more than 5 seconds) would be 3.

Now consider `#0:caller_B', which calls `#0:callee_B' instead of
`#0:callee_A'.  This task would assign 1 to `#0.prop', call
`#0:callee_B', and suspend.  Five seconds later, if the suspended task had
not been killed, then it would resume; it would assign 3 to `#0.prop',
return to `#0:caller', and assign 2 to `#0.prop', ending the task.
So, the final value of `#0.prop' (i.e., the value after more than 5
seconds) would be 2.

A suspended task, like a forked task, can be described by the
`queued_tasks()' function and killed by the `kill_task()' function.
Suspending a task does not change its task id.  A task can be suspended again
and again by successive calls to `suspend()'.

Once `suspend()' has been used in a particular task, then the
`read()' function will always return `E_PERM' in that task.  For more
details, see the description of `read()' below.


task_id()

Syntax:  task_id ()   => num

Returns the numeric identifier for the currently-executing task.  Such numbers
are randomly selected for each task and can therefore safely be used in
circumstances where unpredictability is required.


ticks_left()

Syntax:  ticks_left ()   => num
       seconds_left ()   => num

These two functions return the number of ticks or seconds (respectively) left
to the current task before it will be forcibly terminated.  These are useful,
for example, in deciding when to fork another task to continue a long-lived
computation.


time()

Syntax:  time ()   => num

Returns the current time, represented as the number of seconds that have
elapsed since midnight on 1 January 1970, Greenwich Mean Time.


tonum()

Syntax:  tonum (<value>)   => num

Converts the given MOO value into a number and returns that number.  Object
numbers are converted into the equivalent numbers, strings are parsed as the
decimal encoding of a number, and errors are converted into numbers obeying the
same ordering (with respect to `<=' as the errors themselves.
`tonum()' returns `E_TYPE' if <value> is a list.  If <value>
is a string but the string does not contain a syntactically-correct number,
then `tonum()' returns 0.

    tonum(#34)         =>   34
    tonum("34")        =>   34
    tonum(" - 34  ")   =>  -34
    tonum(E_TYPE)      =>    1


toobj()

Syntax:  toobj (<value>)   => obj

Converts the given MOO value into an object number and returns that object
number.  The conversions are very similar to those for `tonum()' except
that for strings, the number *may* be preceded by `#'.

    toobj("34")       =>   #34
    toobj("#34")      =>   #34
    toobj("foo")      =>   #0
    toobj({1, 2})     -error->   E_TYPE


tostr()

Syntax:  tostr (<value>, ...)   => str

Converts all of the given MOO values into strings and returns the concatenation
of the results.

    tostr(17)                  =>   "17"
    tostr(#17)                 =>   "#17"
    tostr("foo")               =>   "foo"
    tostr({1, 2})              =>   "{list}"
    tostr(E_PERM)              =>   "Permission denied"
    tostr("3 + 4 = ", 3 + 4)   =>   "3 + 4 = 7"

Note that `tostr()' does not do a good job of converting lists into
strings; all lists, including the empty list, are converted into the string
`"{list}"'.


typeof()

Syntax:  typeof (<value>)   => num

Takes any MOO value and returns a number representing the type of <value>.
The result is the same as the initial value of one of these built-in variables:
`NUM', `STR', `LIST', `OBJ', or `ERR'.  Thus, one
usually writes code like this:

    if (typeof(x) == LIST) ...

and not like this:

    if (typeof(x) == 3) ...

because the former is much more readable than the latter.


unlisten()

Syntax:  unlisten (num <port>)   => none

Tells the server to stop listening on <port>.  If the programmer
is not a wizard, `E_PERM' is returned; if no object is listening on
the specified port, `E_VARNF' is returned.

See `help $network:unlisten'[1] for possible non-wizardly access to the unlisten() function.


valid()

Syntax:  valid (obj <object>)   => num

Returns a non-zero number (i.e., a true value) if <object> is a
valid object (one that has been created and not yet recycled) and zero
(i.e., a false value) otherwise.

    valid(#0)    =>   1
    valid(#-1)   =>   0


In almost all cases, you really want to be using $recycler:valid(),
which behaves the same as valid() but additionally returns false if
the object is $garbage.


verb_args()

Syntax:  verb_args (obj <object>, str <verb-name>)   => list
     set_verb_args (obj <object>, str <verb-name>, list <args>)   => none

These two functions get and set (respectively) the direct-object,
preposition, and indirect-object specifications for the verb named
<verb-name> on the given <object>.  If <object> is
not valid, then `E_INVARG' is returned.  If <object> does not
define a verb named <verb-name>, then `E_VERBNF' is returned.
If the programmer does not have read (write) permission on the verb in
question, then `verb_args()' (`set_verb_args()') returns `E_PERM'.
Verb args specifications have the following form:

    {<dobj>, <prep>, <iobj>}

where <dobj> and <iobj> are strings drawn from the set
`"this"', `"none"', and `"any"', and <prep> is a string that is
either `"none"', `"any"', or one of the prepositional phrases listed
much earlier in the description of verbs in the first chapter.  This
is the kind of value returned by `verb_info()' and expected as the
third argument to `set_verb_info()'.  Note that for `set_verb_args()',
<prep> must be only one of the prepositional phrases, not (as is
shown in that table) a set of such phrases separated by `/'
characters.  `Set_verb_args()' returns `E_INVARG' if any of the
<dobj>, <prep>, or <iobj> strings is illegal.

    verb_args($container, "take")
                        =>   {"any", "out of/from inside/from", "this"}
    set_verb_args($container, "take", {"any", "from", "this"})


verb_code()

Syntax:  verb_code (obj <object>, str <verb-name> [, <fully-paren> [, <indent>]])   => list
     set_verb_code (obj <object>, str <verb-name>, list <code>)   => list

These functions get and set (respectively) the MOO-code program associated with
the verb named <verb-name> on <object>.  The program is represented as
a list of strings, one for each line of the program; this is the kind of value
returned by `verb_code()' and expected as the third argument to
`set_verb_code()'.  For `verb_code()', the expressions in the
returned code are usually written with the minimum-necessary parenthesization;
if <full-paren> is true, then all expressions are fully parenthesized.
Also for `verb_code()', the lines in the returned code are usually not
indented at all; if <indent> is true, each line is indented to better show
the nesting of statements.

If <object> is not valid, then `E_INVARG' is returned.  If
<object> does not define a verb named <verb-name>, then `E_VERBNF'
is returned.  If the programmer does not have read (write) permission on the
verb in question, then `verb_code()' (`set_verb_code()') returns
`E_PERM'.  If the programmer is not, in fact. a programmer, then
`E_PERM' is returned.

For `set_verb_code()', the result is a list of strings, the error messages
generated by the MOO-code compiler during processing of <code>.  If the
list is non-empty, then `set_verb_code()' did not install <code>; the
program associated with the verb in question is unchanged.


verb_info()

Syntax:  verb_info (obj <object>, str <verb-name>)   => list
     set_verb_info (obj <object>, str <verb-name>, list <info>)   => none

These two functions get and set (respectively) the owner, permission bits, and
name(s) for the verb named <verb-name> on the given <object>.  If
<object> is not valid, then `E_INVARG' is returned.  If <object>
does not define a verb named <verb-name>, then `E_VERBNF' is returned.
If the programmer does not have read (write) permission on the verb in
question, then `verb_info()' (`set_verb_info()') returns
`E_PERM'.  Verb info has the following form:

    {<owner>, <perms>, <names>}

where <owner> is an object, <perms> is a string containing only
characters from the set `r', `w', `x', and `d', and
<names> is a string.  This is the kind of value returned by
`verb_info()' and expected as the third argument to
`set_verb_info()'; the latter function returns `E_INVARG' if
<owner> is not valid or <perms> contains any illegal characters.


verbs()

Syntax:  verbs (obj <object>)   => list

Returns a list of the names of the verbs defined directly on the given
<object>, not inherited from its parent.  If <object> is not valid,
then `E_INVARG' is returned.  If the programmer does not have read
permission on <object>, then `E_PERM' is returned.


 


help@nwe.ufl.edu
http://web.nwe.ufl.edu/writing/help/moo/jhc/builtin_help.html
Last modified: Tue May 15 14:54:52 2001