Helma Logo
main list history
previous version  overview  next version

Version 6 by hannes on 23. May 2008, 13:07

One of the cornerstones of Helma NG, and one that distinguishes it from every other JavaScript runtime out there, is how it handles modules and scopes.

=== Modules

Helma NG handles JavaScript resources as Modules. If this evokes associations to *Python|http://docs.python.org/tut/node8.html* it is fully intentional, because NG Modules work and feel very much like *Python Modules|http://effbot.org/zone/import-confusion.htm*.

First, if one module wants to make use of another module, it needs to import the other module. Helma NG provides two global functions for this, one to import a module into a discrete namespace, and another to import some or all properties of a module into its own scope.

Now the special thing about Helma NG is that the two modules (one doing the import, the other being imported) are fully isolated from each other. The imported module does not have any way at all to access the importing module, and the importing module can only access the imported one via the namespace into which it imported it, or the properties and functions it explicitly imported from it. And what's more, you don't have to do anything special to accomplish this. You just write scripts with global functions and properties and never worry about stuff that is defined in other scripts.

The way Helma NG does this is by giving each Module its own top-level scope.

=== Module Scope

<% this.image 'scopes-ng-small.png' %>

=== importModule()

=== importFromModule()

=== Module sharing and caching

By default, Helma NG creates earch module once per request. This means that if a module is loaded from several other modules in the same application, you be sure that you deal with the actual same module instance and scope throughout each request, but are isolated from other requests that may be running at the same time.

Sometimes it is desirable to have a module instantiated only once, and shared among all requests. You can achieve this by defining a property called <code>__shared__</code> in your module and giving it the value <code>true</code>:

  var __shared__ = true;

This will result in your module scope to be kept alive across and shared among requests.

=== The shared global scope

=== The per-thread global scope

=== Metaprogramming

Modules automatically recognize functions following the *JSAdapter|http://blogs.sun.com/sundararajan/entry/self_javascript_and_jsadapter* syntax and will invoke these functions for property access if they are defined. For instance, if you define a function called <code>__get__</code> in your module, it will be called to lookup properties. You can access the "raw" properties defined in your modules in your JSAdapter functions.

  var bar = "BAR";
  function __get__(name) {
    if (name == "foobar") {
      return "foo" + bar;
    // leave this away if you don't want to expose "raw" properties
    return this[name];