Namespaces
- prevent naming clashes
- adapted from http://higher-order.blogspot.com/2008/02/designing-clientserver-web-applications.html
- mimics naming of Java packages
- namespace is created with
namespace('lively.test1.test2')- creates namespaces lively, lively.test1, lively.test1.test2 which are all JavaScript objects
- also possible is to pass in a context object, in the following namespace 'lively' must already exist
namespace('test1.test2', lively)
- namespaces can be used directly
lively.test1.newFunction = function() ...
- or via using
using(lively.test1).run(function(theNamespace) { theNamespace.newFunction = function() ... }); - for creating classes in a namespace, the namespace must be explicitly appear in the subclass method
Object.subclass('lively.test1.NewClass', { ...});- Should we extend the subclass method, so that a namespace can be passed in as a parameter?
using(lively.test1).run(function(theNamespace) { Object.subclass('NewClass', theNamespace, { ... }); });
- Should we extend the subclass method, so that a namespace can be passed in as a parameter?
Modules & Require
Modules should provide a simple interface for
- categorizing source code/classes as first class objects,
- preventing name clashes (they create namespaces),
- dynamically loading other modules,
- describe module dependencies,
- finding a source code file e.g. of a class.
They are based on the assumption that a one-to-one relationship between files and module namespaces exist. Problem: this assumption is currently not enforced but Krzysztof mentioned that this would be possible with the freeze operation in ECMAScript 3.1.
The last part of a module name identifies a JavaScript source code file. The module name lively.Tests.FabrikTests would mean that in the directory ./lively/Tests exists a JavaScript file named FabrikTests. At the same time a module lively.Tests.FabrikTests.Test1 could exists. Here FabrikTests resolves to a subdirectory.
Note: Currently lively resolves to the LK base directory.
Current Usage
- Naming conventions
- module('lively.TileScripting') identifies TileScripting.js in the LK Base directory
- module('lively.Tests.TileScriptingTests') identifies TileScriptingTests.js in the subdirectory Tests
- Optionally it is also possible to write module('TileScripting.js') or module('Tests/TileScriptingTests.js') but the namespace style is recommend
- Defining a new module with requirements:
module('lively.Tests.TileScriptingTests').requires('lively.TileScripting', 'lively.Helper').toRun(function(thisModule) { // code which is dependent from TileScripting.js and Helper.js goes here })- the requirements are not loaded in a specific order (which might soon change)
- thisModule is bound to lively.Tests.TileScriptingTests and can be used like theNamespace in the examples above
- just run some code which dependents on another module, great for lazy loading of js files:
require('lively.TileScripting').toRun(function() { lively.TileScripting.TileBox.open() })- Be careful -- code out of the toRun block shouldn't rely on code inside of the block (even if it comes after the require). Code inside a toRun block is run asynchronously.
- Every required module must be defined!
Modules
- created with module function
- also creates namespace
- module function is called with module name which can be something like
- Tests/TileScriptingTests.js --> creates namespace lively.Tests.TileScriptingTests
- lively.Tests.TileScriptingTests --> directly pass in namespace identifier
- a module is a JavaScript object created with the namespace function
- but has also arequires function
Require
- Dynamic loading happens asynchronously, dependent code must be run after all dependencies
- Problem: finding recursive dependencies and waiting
... More to come ...
