Previous chapter To contents Next chapter

Chapter 8, Modules

A module is a software package that plugs into the Pike programming environment. They provide you with simple interfaces to system routines and they also constitute a neat way to use your own C/C++ code from within Pike. Pike comes with a number of modules that are ready to use. In this chapter I will explain the basics of modules and how to use them.

here is a list of the basic Pike modules:

Stdio
This module contains file I/O routines.
Array
This module contains functions that operate on arrays.
Calendar
Support for different calendar and date formats.
Crypto *
Cryptography routines.
Gdbm *
This module contains support for Gdbm databases.
Getopt
Routines to parse command line options
Gmp *
Support for large numbers.
Gz *
Deflate packing algorithms.
Image
Image manipulation routines.
LR
LALR(1) parser generator.
Msql *
Sql database support for the mini-SQL database server.
MIME
Support for coding and decoding MIME.
Mysql *
Sql database support for the mySQL database server.
Process
Functions to start and control other processes.
Protocols
Support for HTTP, NNTP, SMNT, DNS, TELNET and other protocols.
Regexp
Regexp matching routines.
Simulate
Routines to emulate old Pike routines.
String
Routines that operate on strings.
Sql *
Support for ASN1, PKCS and other standards.
Standards
Generic SQL database support.
System
Support for system specific functions.
Thread *
Thread support functions.
Tools
Complete programs available to use from within scripts.
Yp *
Network Information System support.

* These modules might not be available depending on how Pike was compiled and whether support for these functions exist on your system.

8.1 How to use modules

A module is a bunch of functions, programs or other modules collected in one symbol. For instance, the module Stdio contains the objects stdin, stdout and stderr. To access these objects you can write Stdio.stdin, Stdio.stdout or Stdio.stderr anywhere in your program where an object of that type is acceptable. If you use Stdio a lot you can put import Stdio; in the beginning of your program. This will import all the identifiers from the module Stdio into your program, making it possible to write just stdin instead of Stdio.stdin. It is also possible to import all modules in a directory with import by putting the directory name in doublequtes. So, to import all modules in the current directory, you would use import ".";.

8.2 Where do modules come from?

Modules are not loaded until you use them, which saves memory unless you use all the modules. However, if you want to write your own modules it is important to know how modules are located and loaded.

When you use Stdio Pike will look for that module:

  1. In imported directories.
  2. In directories added with add_module_path()
  3. In directories specified with -M on the command line.
  4. In directories in the environment variable PIKE_MODULE_PATH
  5. In the directory with builtin modules, usually /usr/local/lib/pike/modules/
For each of these directories, Pike will do the following:
  1. If there is a file called Stdio.pmod.pike, Pike will load this Pike program, clone it and use that as a module.
  2. If there is a file called Stdio.pmod.so, Pike will load this with load_module(), clone it and use that as a module.
  3. If there is a directory called Stdio.pmod, Pike will create a module containing all the modules in that directory as identifiers. If there is a module called module in that directory, all identifiers from that module will overload any modules actually present in the directory.
As you can see, quite a lot of work goes into finding the modules, this makes it possible to choose the most convenient way to build your own Pike modules.

8.3 The . operator

The period operator is not really an operator, as it is always evaluated during the compilation. It works similarly to the index and arrow operators, but can only be used on constant values such as modules. In most cases, modules are simply a clone of a program, in which case the identifiers in the module will be the same as those in the program. But some modules, like those created from directories, overload the index operator so that the identifiers in the module can be something other than those in the program. For directory modules, the index operator looks in the directory it was cloned for to find the identifiers.

You can also use the . operator without an identifier preceeding it to access modules in the same directory as the program itself. For instance, .my_module.foo would mean 'the identifier foo in the module my_module in this directory.

8.4 How to write a module

Here is an example of a simple module:
constant PI = 3.14159265358979323846264338327950;
float cos2(float f) { return pow(cos(f),2.0); }
if we save this short file as Trig.pmod we can now use this module like this:
int main()
{
    write(sprintf("%f\n",.Trig.cos2(.Trig.PI));
}
or like this:
import .Trig;

int main()
{
    write(sprintf("%f\n",cos2(PI));
}

8.5 Simple exercises

  • Save the hello_world.pike program as hello_world.pike.pmod, then make a program that loads this module and calls its main().
  • Make a directory called Programs.pmod and put all the examples you have written so far in it. Make a program that runs one of those programs. Make sure the program can be modified to run another of your examples by changing what module it loads.
  • Copy the file hello_world.pike.pmod to programs/module.pike.pmod and then write a program that runs hello_world without actually using the identifier hello_world.
  • Try putting Programs.pmod in another directory and then try to run the programs from the last two examples.

  • Previous chapter To contents Next chapter