Manipulating Objects
Objects are, of course, the main focus of most MOO programming and, largely due to that, there are a lot of built-in functions for manipulating them.
Fundamental Operations on Objects
create
obj create(obj parent [, obj owner] [, list init-args])
obj create(list parents [, obj owner] [, list init-args])
Creates and returns a new object whose parent (or parents) is parent (or parents) and whose owner is as described below.
Creates and returns a new object whose parents are parents (or whose parent is parent) and whose owner is as described
below. If any of the given parents are not valid, or if the given parent is neither valid nor #-1, then E_INVARG is
raised. The given parents objects must be valid and must be usable as a parent (i.e., their a
or f
bits must be
true) or else the programmer must own parents or be a wizard; otherwise E_PERM is raised. If the f
bit is not present,
E_PERM is raised unless the programmer owns parents or is a wizard.
E_PERM is also raised 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. If init-args were given, they are passed as args to initialize. 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.
Note: $sysobj is typically #0. Though it can technically be changed to something else, there is no reason that the author knows of to break from convention here.
The owner of the new object is either the programmer (if owner is not provided), the new object itself (if owner was given and is invalid, 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
f 0
The function is_player()
returns false for newly created objects.
In addition, the new object inherits all of the other properties on its parents. These properties have the same
permission bits as on the parents. 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 the parent. The initial value of every inherited property is clear; see the description of the built-in function
clear_property() for details.
If the intended owner of the new object has a property named ownership_quota
and the value of that property is an
integer, 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() raises 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.
owned_objects
list owned_objects(OBJ owner)
Returns a list of all objects in the database owned by owner
. Ownership is defined by the value of .owner on the
object.
chparent
chparent -- Changes the parent of object to be new-parent.
none chparent(obj object, obj new-parent)
If object is not valid, or if new-parent is neither valid nor equal to #-1
, then E_INVARG
is raised. If the
programmer is neither a wizard or the owner of object, or if new-parent is not fertile (i.e., its f
bit is not set)
and the programmer is neither the owner of new-parent nor a wizard, then E_PERM
is raised. If new-parent is equal to
object
or one of its current ancestors, E_RECMOVE
is raised. If object or one of its descendants defines a property
with the same name as one defined either on new-parent or on one of its ancestors, then E_INVARG
is raised.
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 given the same permission
bits as they have on new-parent, 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, and the value of each added property is
clear; see the description of the built-in function clear_property()
for details. All properties that are not
removed or added in the reparenting process are completely unchanged.
If new-parent is equal to #-1
, then object is given no parent at all; it becomes a new root of the parent/child
hierarchy. In this case, all formerly inherited properties on object are simply removed.
valid
int valid(obj object)
Return a non-zero integer if object is valid and not yet recycled.
Returns a non-zero integer (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
Functions: parent
parent -- return the parent of object
obj parent(obj object)
children
list children(obj object)
return a list of the children of object.
isa
int isa(OBJ object, OBJ parent)
obj isa(OBJ object, LIST parent list [, INT return_parent])
Returns true if object is a descendant of parent, otherwise false.
If a third argument is present and true, the return value will be the first parent that object1 descends from in the
parent list
.
isa(#2, $wiz) => 1
isa(#2, {$thing, $wiz, $container}) => 1
isa(#2, {$thing, $wiz, $container}, 1) => #57 (generic wizard)
isa(#2, {$thing, $room, $container}, 1) => #-1
locate_by_name
obj locate_by_name([obj object,] str name [, INT with_key])
object.name
is a string and may optionally contain a key field. The key field is separated from the name by " [", and
its value is delimited by the first space or end of string.
This function is primarily designed to return the best match to name
of the children of object
. This function is
used by the MOO to look for objects referenced via the input functions. This mimics the behavior of the lambda MOO. If
name
is a valid object number, then the object representing that number is returned. If not, the name is tested
against the objects in object.contents
.
If with_key
is specified and true, and a key is supplied in the name, the key is tested against the object key
specified in the objects name. If the object has a key and the key in the name doesn't match, the object is rejected
from the search.
obj:locate_by_name("bar") => #0 (first match)
obj:locate_by_name("foo [3]") => matches object #0 with key "3" only.
obj:locate_by_name("foo [3]", 1) => same as above
obj:locate_by_name("foo [3]", 0) => would return the first "foo" object, ignoring key check
recycle
none recycle(obj object)
destroy object irrevocably.
The given object is destroyed, irrevocably. The programmer must either own object or be a wizard; otherwise, E_PERM
is
raised. If object is not valid, then E_INVARG
is raised. 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 integer, then recycle()
treats that value as a quota and increments it by one, storing the result back
into the ownership_quota
property.
recreate
obj recreate(OBJ old, OBJ parent [, OBJ owner])
Recreate invalid object old (one that has previously been recycle()ed) as parent, optionally owned by owner.
This has the effect of filling in holes created by recycle() that would normally require renumbering and resetting the maximum object.
The normal rules apply to parent and owner. You either have to own parent, parent must be fertile, or you have to be a wizard. Similarly, to change owner, you should be a wizard. Otherwise it's superfluous.
ancestors
list ancestorsOBJ object [, INT full])
Return a list of all ancestors of object
in order ascending up the inheritance hiearchy. If full
is true, object
will be included in the list.
clear_ancestor_cache
void clear_ancestor_cache()
The ancestor cache contains a quick lookup of all of an object's ancestors which aids in expediant property lookups. This is an experimental feature and, as such, you may find that something has gone wrong. If that's that case, this function will completely clear the cache and it will be rebuilt as-needed.
descendants
list descendants(OBJ object [, INT full])
Return a list of all nested children of object. If full is true, object will be included in the list.
object_bytes
int object_bytes(obj object)
Returns the number of bytes of the server's memory required to store the given object.
The space calculation includes the space used by the values of all of the objects non-clear properties and by the verbs and properties defined directly on the object.
Raises E_INVARG
if object is not a valid object and E_PERM
if the programmer is not a wizard.
respond_to
int | list respond_to(OBJ object, STR verb)
Returns true if verb is callable on object, taking into account inheritance, wildcards (star verbs), etc. Otherwise,
returns false. If the caller is permitted to read the object (because the object's
r' flag is true, or the caller is the owner or a wizard) the true value is a list containing the object number of the object that defines the verb and the full verb name(s). Otherwise, the numeric value
1' is returned.
max_object
obj max_object()
Returns the largest object number ever assigned to a created object.
//TODO update for how Toast handles recycled objects if it is different
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()
. The next object getting the number one larger
than max_object()
only applies if you are using built-in functions for creating objects and does not apply if you are
using the $recycler
to create objects.
Object Movement
move
none move(obj what, obj where [, INT position])
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 raised. The programmer must be either the owner of what or a wizard; otherwise, E_PERM
is
raised.
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()
raises 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 raised 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
.
Passing position
into move will effectively listinsert() the object into that position in the .contents list.
Operations on Properties
properties
list properties(obj object)
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 raised. If the programmer does not have read permission on object, then
E_PERM
is raised.
property_info
list property_info(obj object, str prop-name)
Get the owner and permission bits for the property named prop-name on the given object
If object is not valid, then E_INVARG
is raised. If object has no non-built-in property named prop-name, then
E_PROPNF
is raised. If the programmer does not have read (write) permission on the property in question, then
property_info()
raises E_PERM
.
set_property_info
none set_property_info(obj object, str prop-name, list info)
Set the owner and permission bits for the property named prop-name on the given object
If object is not valid, then E_INVARG
is raised. If object has no non-built-in property named prop-name, then
E_PROPNF
is raised. If the programmer does not have read (write) permission on the property in question, then
set_property_info()
raises E_PERM
. Property info has the following form:
{owner, perms [, new-name]}
where owner is an object, perms is a string containing only characters from the set r
, w
, and c
, and new-name is a
string; new-name is never part of the value returned by property_info()
, but it may optionally be given as part of the
value provided to set_property_info()
. This list is the kind of value returned by property_info() and expected as the
third argument to set_property_info()
; the latter function raises E_INVARG
if owner is not valid, if perms contains
any illegal characters, or, when new-name is given, if prop-name is not defined directly on object or new-name names an
existing property defined on object or any of its ancestors or descendants.
add_property
none add_property(obj object, str prop-name, value, list info)
Defines a new property on the given object
The property is 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()
,
described above. If object is not valid or info does not have the correct format, then E_INVARG
is raised. If the
programmer does not have write permission on object, if an ancestor or descendant of object already defines a property
named prop-name, or if the owner specified by info is not valid, then E_PERM
is raised.
delete_property
none delete_property(obj object, str prop-name)
Removes the property named prop-name from the given object.
If object is not valid, then E_INVARG
is raised. If the programmer does not have write permission on object, then
E_PERM
is raised. If object does not directly define a property named prop-name (as opposed to inheriting one from its
parent), then E_PROPNF
is raised.
clear_property
none clear_property(obj object, str prop-name)
Sets the value of the property named prop-name on the given object to 'clear.'
If object is not valid, then E_INVARG
is raised. If object has no non-built-in property named prop-name, then
E_PROPNF
is raised. If the programmer does not have write permission on the property in question, then
clear_property()
raises E_PERM
. clear_property() sets the value of the property to a special value called clear. In
particular, when the property is next read, the value returned will be the value of that property on the parent object.
If the parent object does not have a value for that property, then the grandparent is consulted, and so on. In the
unusual case that there is not even a clear value all the way up to the root object, the value 0 is returned. This
inheritance behavior is the same as if the property had never been assigned a value on the object in question. If the
property had never been defined on the object in question, an attempt to read it would result in E_PROPNF
, but if it
is defined but clear, the inheritance behavior described here applies.
has_property
int has_property(OBJ object, STR name [, INT return_propdef])
Return whether or not the given object has the named property (considering inheritance). When given the optional third argument with a true value, return the object with the property defined on it (taking into account inheritance).
Operations on Verbs
verbs
list verbs(obj object)
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 raised. If the programmer does not have read permission on object, then most
of the remainder of this section on verb-manipulating functions applies:
For the functions described in the next section, if object is not valid, then E_INVARG
is raised. If object does not
define a verb named verb-name, then E_VERBNF
is raised. If the programmer does not have read permission on object,
then E_PERM
is raised.
verb_info
list verb_info(obj object, str verb-name)
Returns a list of three items: the owner of the named verb, a string containing the permission bits for the named verb, and a string containing the names that the named verb can go by.
set_verb_info
none set_verb_info(obj object, str verb-name, list info)
Changes the owner, permission bits, and/or names for the named verb.
Info must be a list of three items as would be returned by verb_info()
, described above.
verb_args
list verb_args(obj object, str verb-name)
Return information about the names and types of the arguments to the named verb
The return value is a list of three items:
- a string containing the direct-object specification for this verb
- a string containing the preposition specification for this verb
- a string containing the indirect-object specification for this verb
The specifications are strings like those allowed in the grammar for verb declarations; see The MOO Programming Language for details.
set_verb_args
none set_verb_args(obj object, str verb-name, list args)
Change the specifications of the arguments for the named verb
Args must be a list of three strings as would be returned by verb_args()
, described above.
add_verb
none add_verb(obj object, list info, list args)
Defines a new verb on the given object.
The new verb's owner, permission bits and names are given by info in the same format as is returned by verb_info()
,
described above. The new verb's direct-, preposition, and indirect-object specifications are given by args in the same
format as is returned by verb_args()
, described above. 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 have the correct format, then E_INVARG
is raised. If the programmer does not
have write permission on object, if the owner specified by info is not valid, or if the programmer is not a wizard and
the owner specified by info is not the same as the programmer, then E_PERM
is raised.
delete_verb
none delete_verb(obj object, str verb-name)
Removes the named verb from the given object.
If object is not valid, then E_INVARG
is raised. If the programmer does not have write permission on object, then
E_PERM
is raised. If object does not define a verb named verb-name, then E_VERBNF
is raised.
verb_code
list verb_code(obj object, str verb-name [, fully-paren [, indent]])
Returns a list of strings giving the MOO-language statements comprising the program for the named verb.
This program is the same collection of statements that would be entered in the editor to change the program for the
named verb. The fully-paren
controls whether or not the program is printed with full parentheses around all
expressions; if fully-paren
is true, then all expressions are fully parenthesized, if false they are printed in the
customary MOO syntax, and if fully-paren
is not provided it defaults to false. The indent
argument controls whether
statements are indented; if indent
is not provided, it defaults to true.
Note that the list returned by verb_code() is not necessarily the same as the one used in a previous call to
set_verb_code()
(described below) to set the program for this verb. The list returned by verb_code()
is always a
canonicalized version of the program: white-space is standardized, comments are removed, etc.
set_verb_code
list set_verb_code(obj object, str verb-name, list program)
Sets the MOO-language program for the named verb to the given list of statements.
The result is a list of strings, the error messages generated by the MOO-language compiler during processing of program. If the result is non-empty, then the operation was not successful and the program for the named verb is unchanged; otherwise, the operation was successful and the program for the named verb is now program.
The elements of program should be strings containing MOO statements; if any of the elements is not a string, then
E_INVARG
is raised. The program need not be syntactically correct MOO; if it is not, then the operation fails and a
non-empty list of compiler error messages is returned. The program may be syntactically correct but suffer from one or
more MOO compile-time semantic errors (e.g., syntax that would exceed certain built-in MOO limits); if so, the operation
fails and a non-empty list of compiler error messages is returned.
If object is not valid, then E_INVARG
is raised. If the programmer does not have write permission on object, then
E_PERM
is raised. If object does not define a verb named verb-name, then E_VERBNF
is raised.
eval
list eval(str string)
The MOO-language expression (or statement) given in string is compiled and evaluated.
The result is a list of two values: a flag indicating whether or not the operation was successful and a value whose interpretation depends upon the success flag. If the flag is true, then the operation was successful and the value is the result of the evaluation. If the flag is false, the operation failed and the value is a list of strings giving error messages generated by the compiler.
The string
is compiled as if it were written on a single line of a verb; in particular, a return statement in string
can return a value from the current verb. The expression (or statement) operates in the context of the current verb
call and has access to the same built-in variables and any verb-local variables.
This operation raises E_INVARG
if the programmer is not, in fact, a programmer.
Object Owners and Wizards
players
list players()
Returns a list of the object numbers of all player objects in the database
is_player
int is_player(obj object)
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 raised.
set_player_flag
none set_player_flag(obj object, value)
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 raised. If the programmer is not a wizard, then E_PERM
is raised.
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 the server will treat a call to
$do_login_command()
that returns object as logging in the current connection.
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).