6. Special Functions

There are some 'functions' in Pike that are not really functions at all but builtin items that can do things that no other functions can do. Some of them can not be re-defined or overloaded. In this chapter I will describe these functions and why they are implemented as special functions.

6.1. sscanf

Sscanf may look exactly like a normal function, but normal functions can not set the variables you send to it. The purpose of sscanf is to match one string against a format string and place the matching results into a list of variables. See sscanf for full documentation.

6.2. catch

Catch is used to trap errors and other exceptions in Pike. It works by making a block of code into an expression, like this:

catch { statements }

If an error occurs, catch will return a description of the error. The description of the error has the following format:

   "error description",

If no error occurs, or if the break statement is encountered, catch will return zero. You may emulate your own errors using the function throw or error.

int x,y;
// This might generate "division by zero"
array error = catch { x/=y; };

6.3. gauge

The syntax for gauge is the same as the syntax for catch:

gauge { statements }

However, gauge simply returns how many seconds the code took to execute. This can be used to find out how fast your code actually is.. :) Only CPU time used by the Pike process is measured. This means that if it takes two seconds to execute but only uses 50 % CPU, this function will return 1.0.

6.4. typeof

This function returns the type of an expression as a string. It does not evaluate the expression at all, which might be somewhat confusing.

typeof( exit(1) )

This will return the string "void" since exit is a function that returns void. It will not execute the function exit and exit the process as you might expect. If you want to know the type after evaluation, use sprintf("%t", expr).

6.5. yield

This function is only valid in restartable functions, and causes the current function to return the value specified, with a restart- point at the call, causing yield to return the first argument given to the function when it is restarted.

    __generator__ int foo(int bar)
      return yield(bar + 10) + 5;

    // function(int:int) foobar = foo(100);
    // foobar() ==> 110;           // ie bar + 10.
    // foobar(10) ==> 15;          // ie 10 + 5.
    // foobar(100) ==> UNDEFINED;  // End of restartable function reached.

6.6. await

This function is similar to yield in that it is only valid in restartable function and causes the current function to return, with a restart-point at the call, but instead of returning its argument, which must be an object API-compatible with Concurrent.Future, it calls Concurrent.Future()->on_await() in the object with continue::this_function as the argumnet and returns UNDEFINED from the current function. This causes it to resume with the success value of the promise or throw the failure value.

    __async__ int foo(Concurrent.Future f)
      return await(f) + 5;

    // Concurrent.Promise p = Concurrent.Promise();
    // Concurrent.Future f = foo(p->future());
    // p->success(10);
    // f->get() ==> 15;