Aside from the above functions, which are expected from the Pike binary,
the master object is also expected to provide functions used by Pike
scripts. The current master object adds the following global functions:
There are at least two ways to change the behavior of the master object.
(Except for editing it directly, which would cause other Pike scripts not
to run in most cases.) You can either copy the master object, modify it
and use the command line option -m to load your file instead of
the default master object. However, since there might be more functionality
added to the master object in the future I do not recommend this.
A better way is to write an object that inherits the master and then calls
replace_master with the new object as argument. This should be far more
future-safe. Although I can not guarantee that the interface between Pike
and the master object will not change in the future, so be careful if you
do this.
Let's look an example:
17.1 The master object
Pike is a very dynamic language. Sometimes that is not enough, sometimes you
want to change the way Pike handles errors, loads modules or start scripts.
All this and much more can be changed by modifying the master object.
The master object is a Pike object like any other object, but it is
loaded before anything else and is expected to perform certain things for
the Pike executable. The Pike executable cannot function without a master
object to take care of these things. Here is a list of the methods needed
in the master object:
This example installs a master object which logs run time errors to file
instead of writing them to stderr.
#!/usr/local/bin/pike
class new_master {
inherit "/master";
void create()
{
/* You need to copy the values from the old master to the new */
/* NOTE: At this point we are still using the old master */
object old_master = master();
object new_master = this_object();
foreach(indices(old_master), string varname)
{
/* The catch is needed since we can't assign constants */
catch { new_master[varname] = old_master[varname]; };
}
}
void handle_error(array trace)
{
Stdio.write_file("error log",describe_backtrace(trace));
}
};
int main(int argc, array(string) argv)
{
replace_master(new_master());
/* Run rest of program */
exit(0);
}
A struct svalue has three members:
type is: | member to use: | notes: |
---|---|---|
T_INT | INT_TYPE integer | |
T_FLOAT | FLOAT_TYPE float_number | |
T_STRING | struct pike_string *string | |
T_ARRAY | struct array *array | |
T_MAPPING | struct mapping *mapping | |
T_MULTISET | struct multiset *multiset | |
T_OBJECT | struct object *object | |
T_PROGRAM | struct program *program | |
T_FUNCTION | struct callable *efun | If subtype == FUNCTION_BUILTIN |
T_FUNCTION | struct object *object | If subtype != FUNCTION_BUILTIN |
Of course there are a whole bunch of functions for operating on svalues:
This macro may call Pike code and/or error().
int is_le(struct svalue *a, struct svalue *b);
int is_gt(struct svalue *a, struct svalue *b);
int is_ge(struct svalue *a, struct svalue *b);
A struct pike_string has these members:
If after calling this function you decide that you do not need this string after all, you can simply call free on the returned string to free it. It is also possible to call free_string(end_shared_string(s)) but that would be much less efficient.
A struct array has these members:
void prtypes(struct array *a)
{
INT e;
for(e=0;e<a->size;e++)
printf("Element %d is of type %d\n",e,a->item[e].type);
}
This is the contents of a struct mapping:
Below is an illustration which shows an example of a small mapping with hash table, free list and key-index pairs.