Interface
L'interface fonctionnelle de So-o en JavaScript est constituée de 3 fonctions :
defclass
qui définit une nouvelle classe, sendmsg
qui sert systématiquement à envoyer un message à une classe ou à une instance, et supersend
qui exécute une méthode héritée d'une superclasse.
Tout le code de l'interface de So-o est dans le fichier So-o.js.
- import 'Root';
Charger le code de So-o inclut automatiquement la classe Root.
defclass
SYNOPSIS
defclass(name, superclass, revision, classProperties, instanceProperties, classMessages, instanceMessages)
DESCRIPTION
defclass
définit une classe.
name
spécifie le nom de la classe. name
doit être un nom de variable JavaScript valide.
superclass
est la référence globale de la superclasse de la nouvelle classe.
Si superclass
vaut null
, la nouvelle classe hérite de la classe Root, Root
.
revision
donne le numéro de révision de la classe. revision
est un entier > 0 qui peut servir à différencier des versions successives de la classe.
classProperties
et instanceProperties
listent les propriétés de la classe et des instances de la classe.
Une propriété est une chaîne de caractères.
classMessages
et instanceMessages
sont des listes associatives de messages et de méthodes de la classe et des instances de la classe.
Un message est une chaîne de caractères.
Une méthode est le code d'une fonction.
Chacun des paramètres classProperties
, instanceProperties
, classMessages
et instanceMessages
peut être null
.
defclass
crée la variable globale name
.
Remarquez qu'une classe peut être redéfinie.
Une nouvelle classe reçoit automatiquement le message initialize.
NOTE : La méthode de classe initialize
définie par la classe Root ne fait rien.
EXEMPLE
- import { defclass } from 'So-o';
Importe la fonction defclass
de So-o.
Le fichier So-o.js inclut automatiquement la classe Root.
- defclass('Hello', null, 1,
- null,
- null,
- null,
- { 'hello': (self) => {
- console.log('Hello from So-o!');
- return self;
- }
- }
- );
Définit la classe Hello et l'associe à la variable globale Hello
.
La classe Hello hérite par défaut de la classe Root.
Son numéro de révision vaut 1.
Elle n'a pas de propriétés de classe, de messages de classe ni de propriétés d'instance.
Elle a un message d'instance : hello.
Une méthode est une fonction dont le premier argument est la classe ou l'instance qui reçoit le message.
Conventionnellement, cet argument a pour nom de variable self
.
Une méthode qui n'a rien de particulier à retourner retourne généralement self
.
Quelques lignes de code pour illustrer l'utilisation de la classe Hello
:
- import { sendmsg } from 'So-o';
- import 'Hello';
- var hello = sendmsg(Hello, 'new');
- sendmsg(hello, 'hello');
Importe la fonction sendmsg
de So-o.
Importe la classe Hello.
Envoie le message new à la classe Hello pour créer l'instance hello
en lui affectant la valeur retournée par sendmsg
.
Envoie le message hello à l'instance hello
pour afficher le message de bienvenue.
$ ln Hello.js node_modules/Hello.mjs
$ ln testHello.js testHello.mjs
$ nodejs --experimental-modules testHello
Hello from So-o!
CODE
- import { Definition } from 'OL';
Importe le prototype Definiton
de l'Object Layer.
- export function defclass(name, superclass, revision, classProperties, instanceProperties, classMessages, instanceMessages) {
defclass
prend 7 arguments.
name
spécifie le nom de la classe.
superclass
est la référence globale de la superclasse de la nouvelle classe.
revision
donne le numéro de révision de la classe.
classProperties
, instanceProperties
, classMessages
et instanceMessages
listent les propriétés et les méthodes de la classe et des instances de la classe.
- let c = new Definition(name, superclass, revision, classProperties, instanceProperties, classMessages, instanceMessages);
Crée un objet du type Definition définie par l'Object Layer avec les paramètres de l'appel de defclass
.
- global[name] = c;
Assigne la définition à une variable globale dont le nom est le nom de la classe.
- if ('Root' !== name)
- sendmsg(c, 'initialize');
Envoie le message initialize à la nouvelle classe si ce n'est pas la classe Root.
- return c;
- }
Retourne la classe.
sendmsg
SYNOPSIS
sendmsg(rcv, msg[, arg ...])
DESCRIPTION
sendmsg
retourne le résultat de l'envoi du message msg
et de ses paramètres arg
à l'instance ou à la classe rcv
.
CODE
- export function sendmsg(rcv, msg, ...args) {
- return rcv.sendself(msg, args);
- }
sendmsg
appelle la fonction sendself
de rcv
avec en argument msg
et un tableau contenant tous les autres arguments suivants msg
.
supersend
SYNOPSIS
sendmsg(fc, rcv, msg[, arg ...])
DESCRIPTION
supersend
retourne le résultat de l'envoi du message msg
et de ses paramètres à l'instance ou à la classe rcv
dans le contexte de la superclasse de la classe fc
.
supersend
sert généralement à appeler la version héritée d'une méthode qui est redéfinie par une sous-classe.
Dans ce cas, fc
est la classe de la méthode qui redéfinit msg
et appelle supersend
.
CODE
- export function supersend(fc, rcv, msg, ...args) {
- return rcv.sendsuper(fc, msg, args);
- }
supersend
appelle la fonction sendsuper
de rcv
avec en argument fc
, msg
et un tableau contenant tous les autres arguments suivant msg
.
EXEMPLE
- import { defclass, sendmsg, supersend } from 'So-o';
Importe les fonctions defclass
, sendmsg
et supersend
de So-o.
- defclass('X', null, 1,
- ['count'],
- ['value'],
La classe X hérite de la class Root, ajoute la propriété de classe count et la propriété d'instance value, redéfinit les messages de classe initialize et new, ajoute le message de classe count, redéfinit les messages d'instance init et free.
- { 'new': (self, ...args) => {
- let i = supersend(X, self, 'new', ...args);
- sendmsg(self, 'set', 'count', sendmsg(self, 'get', 'count') + 1);
- return i;
- },
new crée une instance de X en appelant la méthode new héritée de la superclasse de X avec tous les arguments de l'appel. NOTE : La méthode new de la classe Root passe ses arguments à la méthode d'instance init qui est redéfinie par la classe X.
- 'initialize': (self) => sendmsg(self, 'set', 'count', 0),
initialize met la propriété de classe count à 0. NOTE : initialize est appelée une fois automatiquement par defclass
.
- 'count': (self) => sendmsg(self, 'get', 'count')
- },
count retourne la valeur de la propriété de classe count.
- { 'init': (self, value = 0) => {
- supersend(X, self, 'init');
- sendmsg(self, 'set', 'value', value);
- return self;
- },
init appelle la méthode init héritée de la superclasse de X et initialise la propriété d'instance value.
- 'free': (self) => {
- let count = sendmsg(sendmsg(self, 'class'), 'get', 'count');
- sendmsg(sendmsg(self, 'class'), 'set', 'count', count -1);
- supersend(X, self, 'free');
- }
- }
- );
free décrémente de 1 le compteur d'instances de la classe X et appelle la méthode free héritée de la superclasse de X.
- import { sendmsg } from 'So-o';
- import 'X';
- console.log(sendmsg(X, 'count'));
Importe la fonction sendmsg
de So-o.
Importe la classe X. Affiche le compteur d'instances de la classe X.
- let x1 = sendmsg(X, 'new');
- console.log(sendmsg(x1, 'get', 'value'));
Crée une instance de X avec la valeur par défaut. Affiche la valeur de l'instance.
- let x2 = sendmsg(X, 'new', 1);
- console.log(sendmsg(x2, 'get', 'value'));
Crée une instance de X avec la valeur 1. Affiche la valeur de l'instance.
- console.log(sendmsg(X, 'count'));
Affiche le compteur d'instances de la classe X.
- sendmsg(x1, 'free');
- x1 = undefined;
- console.log(sendmsg(X, 'count'));
Libère une instance de X. Affiche le compteur d'instances de la classe X.
$ ln X.js node_modules/X.mjs
$ ln testX.js test.mjs
$ nodejs --experimental-modules testX
0
0
1
2
1
Commentaires