Websites Navigation: Airbit | Shop | m-shell.net
Languages: EN | DE

Making it a Module

Before we add all the pieces together, we want to introduce a last concept: modularization. Remember we have written three functions:
  • function edit(table) to edit a database table,
  • function save(table, file) to save a database table to a file.
  • function load(file) to load a database table from a file.
These three functions can manage any database of key-text pairs, not just the keywords and replies for our SMS service. We should therefore make them generally available, and create a module from them.

We will call our module MyDB. The module is part of the standard installation, so you don't have to create it with mShell→New Module:

   
Series 60 sample screen
UIQ sample screen

Instead, you can simply open MyDb to look at the module code below:


/**
   A simple key-data database.
*/
use io, array, ui

/**
   Load the database from a file.
   @param file the file to load the database from.
   @return the database.
*/
function load(file="table.dat")
  try
    f=io.open(file);
    table=io.readm(f);
    io.close(f);
    return table
  catch e by
    return []
  end
end


/**
   Save the database to a file.
   @param table the database to save.
   @param file the file to save the database to.
*/
function save(table, file="table.dat")
  f=io.create(file);
  io.writem(f, table);
  io.close(f)
end


/**
   Present a user interface to edit a database.
   @param table the database to edit.
*/
function edit(table)
  while true do
    list=keys(table);
    array.sort(list);
    array.insert(list, 0, "<New>");
    i=ui.list(list);
    if i=null then break end;
    i=i[0];
    if i=0 then
      f=ui.form(["Key":"","Text":"\n"]);
      if f#null then
        k=f["Key"];
        if table[k]=null then table[k]=f["Text"]
        else ui.error(k + " already exists") end
      end
    else
      k=list[i];
      f=ui.form([k,"Text":table[k]+"\n"]);
      if f#null then table[k]=f["Text"] end
    end
  end  
end

Remarks:

  • The module source is, like a script source, just a sequence of m use clauses, function definitions and statements. Outside the module, the functions and variables will be accessible by prefixing them with the module name, e.g. MyDB.load.
  • Since a module will be read by others who are trying to understand what it has offer, it is a good idea to add comments. Multi-line comments start with slash-star (/*), and end with star-slash (*/). All characters in between are ignored by m. We recommend the tags @param and @return known from Java™ to comment on parameters and return values.
To finish, we have a look at SmsService, which uses MyDB:

/**
   A configurable SMS service.
*/
use sms, mydb, ui

const file="SmsService.dat";
db=mydb.load(file);
ui.menu("Service",["Edit","Stop"]);
do
  id=sms.receive(1000);
  if id#null then
    msg=sms.get(id);
    t=lower(trim(msg["text"]));
    if db[t]#null then
      print "Got",t,"from",msg["sender"];
      sms.send(msg["sender"], db[t]);
      sms.delete(id)
    end
  end;
  cmd=ui.cmd(5000);
  if cmd="Edit" then
    mydb.edit(db); mydb.save(db, file)
  end
until cmd="Stop"

Remarks:

  • The mydb in the use list makes sure the MyDB module is loaded. Note that, unlike variables and functions, module names are not case sensitive. This is because names in the Symbian OS file system are not save sensitive, so the modules MyDB and mydb cannot be distinguished.
  • The database is written to and read from file SmsService.dat. We assign this to variable file and make it const, so it cannot be modified. This is not really necessary; it is mainly a hint to the human reader.
  • Before the service starts receiving SMS, we load the database by calling a function from our module: mydb.load(file).
  • Every time the database has been edited, it is saved: mydb.edit() is immediately followed by mydb.save().
And that's all there is!


© 2004-2011 airbit AG, CH-8008 Zürich
Document AB-M-TUT-887
mShell Home  > Documentation  > Manuals