<HTML> <HEAD> <!-- This HTML file has been created by texi2html 1.51 from ProgrammersManual.texinfo on 4 March 1997 --> <TITLE>LambdaMOO Programmer's Manual - Evaluation and Tasks</TITLE> </HEAD> <BODY> Go to the <A HREF="ProgrammersManual_1.html">first</A>, <A HREF="ProgrammersManual_53.html">previous</A>, <A HREF="ProgrammersManual_55.html">next</A>, <A HREF="ProgrammersManual_77.html">last</A> section, <A HREF="ProgrammersManual_toc.html">table of contents</A>. <P><HR><P> <H3><A NAME="SEC54" HREF="ProgrammersManual_toc.html#TOC54">MOO-Code Evaluation and Task Manipulation</A></H3> <P> <DL> <DT><U>Function:</U> none <B>raise</B> <I>(<VAR>code</VAR> [, str <VAR>message</VAR> [, <VAR>value</VAR>]])</I> <DD><A NAME="IDX103"></A> Raises <VAR>code</VAR> as an error in the same way as other MOO expressions, statements, and functions do. <VAR>Message</VAR>, which defaults to the value of <CODE>tostr(<VAR>code</VAR>)</CODE>, and <VAR>value</VAR>, which defaults to zero, are made available to any <CODE>try</CODE>-<CODE>except</CODE> statements that catch the error. If the error is not caught, then <VAR>message</VAR> will appear on the first line of the traceback printed to the user. </DL> </P> <P> <DL> <DT><U>Function:</U> value <B>call_function</B> <I>(str <VAR>func-name</VAR>, <VAR>arg</VAR>, ...)</I> <DD><A NAME="IDX104"></A> Calls the built-in function named <VAR>func-name</VAR>, passing the given arguments, and returns whatever that function returns. Raises <CODE>E_INVARG</CODE> if <VAR>func-name</VAR> is not recognized as the name of a known built-in function. This allows you to compute the name of the function to call and, in particular, allows you to write a call to a built-in function that may or may not exist in the particular version of the server you're using. </DL> </P> <P> <DL> <DT><U>Function:</U> list <B>function_info</B> <I>([str <VAR>name</VAR>])</I> <DD><A NAME="IDX105"></A> Returns descriptions of the built-in functions available on the server. If <VAR>name</VAR> is provided, only the description of the function with that name is returned. If <VAR>name</VAR> is omitted, a list of descriptions is returned, one for each function available on the server. Raised <CODE>E_INVARG</CODE> if <VAR>name</VAR> is provided but no function with that name is available on the server. </P> <P> Each function description is a list of the following form: </P> <PRE> {<VAR>name</VAR>, <VAR>min-args</VAR>, <VAR>max-args</VAR>, <VAR>types</VAR> </PRE> <P> where <VAR>name</VAR> is the name of the built-in function, <VAR>min-args</VAR> is the minimum number of arguments that must be provided to the function, <VAR>max-args</VAR> is the maximum number of arguments that can be provided to the function or <CODE>-1</CODE> if there is no maximum, and <VAR>types</VAR> is a list of <VAR>max-args</VAR> integers (or <VAR>min-args</VAR> if <VAR>max-args</VAR> is <CODE>-1</CODE>), each of which represents the type of argument required in the corresponding position. Each type number is as would be returned from the <CODE>typeof()</CODE> built-in function except that <CODE>-1</CODE> indicates that any type of value is acceptable and <CODE>-2</CODE> indicates that either integers or floating-point numbers may be given. For example, here are several entries from the list: </P> <PRE> {"listdelete", 2, 2, {4, 0}} {"suspend", 0, 1, {0}} {"server_log", 1, 2, {2, -1}} {"max", 1, -1, {-2}} {"tostr", 0, -1, {}} </PRE> <P> <CODE>Listdelete()</CODE> takes exactly 2 arguments, of which the first must be a list (<CODE>LIST == 4</CODE>) and the second must be an integer (<CODE>INT == 0</CODE>). <CODE>Suspend()</CODE> has one optional argument that, if provided, must be an integer. <CODE>Server_log()</CODE> has one required argument that must be a string (<CODE>STR == 2</CODE>) and one optional argument that, if provided, may be of any type. <CODE>Max()</CODE> requires at least one argument but can take any number above that, and the first argument must be either an integer or a floating-point number; the type(s) required for any other arguments can't be determined from this description. Finally, <CODE>tostr()</CODE> takes any number of arguments at all, but it can't be determined from this description which argument types would be acceptable in which positions. </DL> </P> <P> <DL> <DT><U>Function:</U> list <B>eval</B> <I>(str <VAR>string</VAR>)</I> <DD><A NAME="IDX106"></A> The MOO-code compiler processes <VAR>string</VAR> 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 <CODE>E_PERM</CODE> is raised. The normal result of calling <CODE>eval()</CODE> 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). </P> <P> When the fictional verb is invoked, the various built-in variables have values as shown below: </P> <PRE> player the same as in the calling verb this #-1 caller the same as the initial value of <CODE>this</CODE> in the calling verb args {} argstr "" verb "" dobjstr "" dobj #-1 prepstr "" iobjstr "" iobj #-1 </PRE> <P> The fictional verb runs with the permissions of the programmer and as if its <SAMP>`d'</SAMP> permissions bit were on. </P> <PRE> eval("return 3 + 4;") => {1, 7} </PRE> </DL> <P> <DL> <DT><U>Function:</U> none <B>set_task_perms</B> <I>(obj <VAR>who</VAR>)</I> <DD><A NAME="IDX107"></A> Changes the permissions with which the currently-executing verb is running to be those of <VAR>who</VAR>. If the programmer is neither <VAR>who</VAR> nor a wizard, then <CODE>E_PERM</CODE> is raised. </P> <BLOCKQUOTE> <P> <STRONG>Note</STRONG>: 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. </BLOCKQUOTE> </DL> <P> <DL> <DT><U>Function:</U> obj <B>caller_perms</B> <I>()</I> <DD><A NAME="IDX108"></A> 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 <CODE>caller_perms()</CODE> returns <CODE>#-1</CODE>. </DL> </P> <P> <DL> <DT><U>Function:</U> int <B>ticks_left</B> <I>()</I> <DD><A NAME="IDX109"></A> <DT><U>Function:</U> int <B>seconds_left</B> <I>()</I> <DD><A NAME="IDX110"></A> 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 call <SAMP>`suspend()'</SAMP> to continue a long-lived computation. </DL> </P> <P> <DL> <DT><U>Function:</U> int <B>task_id</B> <I>()</I> <DD><A NAME="IDX111"></A> Returns the non-zero, non-negative integer identifier for the currently-executing task. Such integers are randomly selected for each task and can therefore safely be used in circumstances where unpredictability is required. </DL> </P> <P> <DL> <DT><U>Function:</U> value <B>suspend</B> <I>([int <VAR>seconds</VAR>])</I> <DD><A NAME="IDX112"></A> Suspends the current task, and resumes it after at least <VAR>seconds</VAR> seconds. (If <VAR>seconds</VAR> is not provided, the task is suspended indefinitely; such a task can only be resumed by use of the <CODE>resume()</CODE> function.) 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 <VAR>seconds</VAR> is negative, then <CODE>E_INVARG</CODE> is raised. <CODE>Suspend()</CODE> returns zero unless it was resumed via <CODE>resume()</CODE>, in which case it returns the second argument given to that function. </P> <P> In some sense, this function forks the `rest' of the executing task. However, there is a major difference between the use of <SAMP>`suspend(<VAR>seconds</VAR>)'</SAMP> and the use of the <SAMP>`fork (<VAR>seconds</VAR>)'</SAMP>. The <SAMP>`fork'</SAMP> statement creates a new task (a <STRONG>forked task</STRONG>) while the currently-running task still goes on to completion, but a <CODE>suspend()</CODE> suspends the currently-running task (thus making it into a <STRONG>suspended task</STRONG>). This difference may be best explained by the following examples, in which one verb calls another: </P> <PRE> .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; . </PRE> <P> Consider <CODE>#0:caller_A</CODE>, which calls <CODE>#0:callee_A</CODE>. Such a task would assign 1 to <CODE>#0.prop</CODE>, call <CODE>#0:callee_A</CODE>, fork a new task, return to <CODE>#0:caller_A</CODE>, and assign 2 to <CODE>#0.prop</CODE>, 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 <CODE>#0.prop</CODE> and then stop. So, the final value of <CODE>#0.prop</CODE> (i.e., the value after more than 5 seconds) would be 3. </P> <P> Now consider <CODE>#0:caller_B</CODE>, which calls <CODE>#0:callee_B</CODE> instead of <CODE>#0:callee_A</CODE>. This task would assign 1 to <CODE>#0.prop</CODE>, call <CODE>#0:callee_B</CODE>, and suspend. Five seconds later, if the suspended task had not been killed, then it would resume; it would assign 3 to <CODE>#0.prop</CODE>, return to <CODE>#0:caller_B</CODE>, and assign 2 to <CODE>#0.prop</CODE>, ending the task. So, the final value of <CODE>#0.prop</CODE> (i.e., the value after more than 5 seconds) would be 2. </P> <P> A suspended task, like a forked task, can be described by the <CODE>queued_tasks()</CODE> function and killed by the <CODE>kill_task()</CODE> function. Suspending a task does not change its task id. A task can be suspended again and again by successive calls to <CODE>suspend()</CODE>. </P> <P> By default, there is no limit to the number of tasks any player may suspend, but such a limit can be imposed from within the database. See the chapter on server assumptions about the database for details. </DL> </P> <P> <DL> <DT><U>Function:</U> none <B>resume</B> <I>(int <VAR>task-id</VAR> [, <VAR>value</VAR>])</I> <DD><A NAME="IDX113"></A> Immediately ends the suspension of the suspended task with the given <VAR>task-id</VAR>; that task's call to <CODE>suspend()</CODE> will return <VAR>value</VAR>, which defaults to zero. If <VAR>value</VAR> is of type <CODE>ERR</CODE>, it will be raised, rather than returned, in the suspended task. <CODE>Resume()</CODE> raises <CODE>E_INVARG</CODE> if <VAR>task-id</VAR> does not specify an existing suspended task and <CODE>E_PERM</CODE> if the programmer is neither a wizard nor the owner of the specified task. </DL> </P> <P> <DL> <DT><U>Function:</U> list <B>queue_info</B> <I>([obj <VAR>player</VAR>])</I> <DD><A NAME="IDX114"></A> If <VAR>player</VAR> is omitted, returns a list of object numbers naming all players that currently have active task queues inside the server. If <VAR>player</VAR> is provided, returns the number of background tasks currently queued for that user. It is guaranteed that <CODE>queue_info(<VAR>X</VAR>)</CODE> will return zero for any <VAR>X</VAR> not in the result of <CODE>queue_info()</CODE>. </DL> </P> <P> <DL> <DT><U>Function:</U> list <B>queued_tasks</B> <I>()</I> <DD><A NAME="IDX115"></A> Returns information on each of the background tasks (i.e., forked, suspended or reading) 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: </P> <PRE> {<VAR>task-id</VAR>, <VAR>start-time</VAR>, <VAR>x</VAR>, <VAR>y</VAR>, <VAR>programmer</VAR>, <VAR>verb-loc</VAR>, <VAR>verb-name</VAR>, <VAR>line</VAR>, <VAR>this</VAR>} </PRE> <P> where <VAR>task-id</VAR> is an integer identifier for this queued task, <VAR>start-time</VAR> is the time after which this task will begin execution (in <CODE>time()</CODE> format), <VAR>x</VAR> and <VAR>y</VAR> are obsolete values that are no longer interesting, <VAR>programmer</VAR> is the permissions with which this task will begin execution (and also the player who <STRONG>owns</STRONG> this task), <VAR>verb-loc</VAR> is the object on which the verb that forked this task was defined at the time, <VAR>verb-name</VAR> is that name of that verb, <VAR>line</VAR> is the number of the first line of the code in that verb that this task will execute, and <VAR>this</VAR> is the value of the variable <SAMP>`this'</SAMP> in that verb. For reading tasks, <VAR>start-time</VAR> is <CODE>-1</CODE>. </P> <P> The <VAR>x</VAR> and <VAR>y</VAR> fields are now obsolete and are retained only for backward-compatibility reasons. They may be reused for new purposes in some future version of the server. </DL> </P> <P> <DL> <DT><U>Function:</U> none <B>kill_task</B> <I>(int <VAR>task-id</VAR>)</I> <DD><A NAME="IDX116"></A> Removes the task with the given <VAR>task-id</VAR> from the queue of waiting tasks. If the programmer is not the owner of that task and not a wizard, then <CODE>E_PERM</CODE> is raised. If there is no task on the queue with the given <VAR>task-id</VAR>, then <CODE>E_INVARG</CODE> is raised. </DL> </P> <P> <DL> <DT><U>Function:</U> list <B>callers</B> <I>([<VAR>include-line-numbers</VAR>])</I> <DD><A NAME="IDX117"></A> Returns information on each of the verbs and built-in functions currently waiting to resume execution in the current task. When one verb or function calls another verb or function, execution of the caller is temporarily suspended, pending the called verb or function returning a value. At any given time, there could be several such pending verbs and functions: the one that called the currently executing verb, the verb or function that called that one, and so on. The result of <CODE>callers()</CODE> is a list, each element of which gives information about one pending verb or function in the following format: </P> <PRE> {<VAR>this</VAR>, <VAR>verb-name</VAR>, <VAR>programmer</VAR>, <VAR>verb-loc</VAR>, <VAR>player</VAR>, <VAR>line-number</VAR>} </PRE> <P> For verbs, <VAR>this</VAR> is the initial value of the variable <SAMP>`this'</SAMP> in that verb, <VAR>verb-name</VAR> is the name used to invoke that verb, <VAR>programmer</VAR> is the player with whose permissions that verb is running, <VAR>verb-loc</VAR> is the object on which that verb is defined, <VAR>player</VAR> is the initial value of the variable <SAMP>`player'</SAMP> in that verb, and <VAR>line-number</VAR> indicates which line of the verb's code is executing. The <VAR>line-number</VAR> element is included only if the <VAR>include-line-numbers</VAR> argument was provided and true. </P> <P> For functions, <VAR>this</VAR>, <VAR>programmer</VAR>, and <VAR>verb-loc</VAR> are all <CODE>#-1</CODE>, <VAR>verb-name</VAR> is the name of the function, and <VAR>line-number</VAR> is an index used internally to determine the current state of the built-in function. The simplest correct test for a built-in function entry is </P> <PRE> (VERB-LOC == #-1 && PROGRAMMER == #-1 && VERB-NAME != "") </PRE> <P> The first element of the list returned by <CODE>callers()</CODE> 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. </DL> </P> <P> <DL> <DT><U>Function:</U> list <B>task_stack</B> <I>(int <VAR>task-id</VAR> [, <VAR>include-line-numbers</VAR>])</I> <DD><A NAME="IDX118"></A> Returns information like that returned by the <CODE>callers()</CODE> function, but for the suspended task with the given <VAR>task-id</VAR>; the <VAR>include-line-numbers</VAR> argument has the same meaning as in <CODE>callers()</CODE>. Raises <CODE>E_INVARG</CODE> if <VAR>task-id</VAR> does not specify an existing suspended task and <CODE>E_PERM</CODE> if the programmer is neither a wizard nor the owner of the specified task. </DL> </P> <P><HR><P> Go to the <A HREF="ProgrammersManual_1.html">first</A>, <A HREF="ProgrammersManual_53.html">previous</A>, <A HREF="ProgrammersManual_55.html">next</A>, <A HREF="ProgrammersManual_77.html">last</A> section, <A HREF="ProgrammersManual_toc.html">table of contents</A>. </BODY> </HTML>