Interface
L'interface fonctionnelle de So-o en PHP 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.php.
- require_once 'OL.php';
- require_once 'Object.php';
Charger le code de So-o inclut le code de l'Object Layer et de la classe Object.
defclass
SYNOPSIS
defclass($name, $superclass, $revision, $class_properties, $instance_properties, $class_messages, $instance_messages)
DESCRIPTION
defclass
définit une classe.
$name
spécifie le nom de la classe. $name
doit être un nom de variable PHP 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 Object, $Object
.
$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.
$class_properties
, $instance_properties
, $class_messages
et $instance_messages
listent les propriétés et les messages de la classe et des instances de la classe.
Chacun de ces paramètres est un tableau de chaînes de caractères ou null
.
Une propriété ou un message doit être un nom de variable PHP valide.
defclass
crée la variable globale $name
.
Remarquez qu'une classe peut être redéfinie.
En cas d'erreur, defclass
déclenche une exception InvalidArgumentException.
Une nouvelle classe reçoit automatiquement le message initialize.
NOTE : La méthode de classe initialize
définie par la classe Object ne fait rien.
EXEMPLE
- namespace Hello;
La classe Hello est définie dans un espace de nommage du même nom. Une classe place toujours son code dans son propre espace de nommage.
- require_once 'So-o.php';
Charge le code de So-o. Le fichier So-o.php inclut automatiquement la classe Object.
- defclass('Hello', null, 1, null, null, null, array('hello'));
Définit la classe Hello et l'associe à la variable globale $Hello
.
La classe Hello hérite par défaut de la classe Object.
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.
- function i_hello($self) {
- echo 'Hello from So-o!', PHP_EOL;
- return $self;
- }
Définit le code du message d'instance hello.
Une méthode d'instance est une fonction qui a comme nom un message d'instance préfixé par i_
.
Une méthode de classe est une fonction qui a comme nom un message de classe préfixé par c_
.
Une méthode de classe ou d'instance est définie dans l'espace de nommage de la classe.
Une méthode a toujours comme premier argument 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
.
$ php -a
php > require_once 'Hello.php';
php > echo $Hello;
class(Hello)
php > $hello=sendmsg($Hello, 'new');
php > echo $hello;
object(Hello)
php > sendmsg($hello, 'hello');
Hello from So-o!
CODE
- function defclass($name, $superclass, $revision, $class_properties, $instance_properties, $class_messages, $instance_messages) {
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.
$class_properties
, $instance_properties
, $class_messages
et $instance_messages
listent les propriétés et les messages de la classe et des instances de la classe.
- $class=new \OL\Definition($name, $superclass, $revision, $class_properties, $instance_properties, $class_messages, $instance_messages);
Crée un objet de la classe Definition définie par l'Object Layer dans l'espace de nommage OL avec les paramètres de l'appel de defclass
.
- $GLOBALS[$name]=$class;
Assigne la classe à une variable globale dont le nom est le nom de la classe.
- if ('Object' != $name) {
- \OL\class_send_message($class, 'initialize');
- }
Envoie le message initialize à la nouvelle classe si ce n'est pas la classe Object.
- return $class;
- }
Retourne la classe.
sendmsg
SYNOPSIS
sendmsg($receiver, $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 $receiver
.
CODE
- function sendmsg($receiver, $msg) {
- return $receiver->sendself($msg, array_slice(func_get_args(), 2));
- }
sendmsg
appelle la méthode sendself
de $receiver
avec en argument $msg
et un tableau contenant tous les autres arguments suivants $msg
.
supersend
SYNOPSIS
supersend($msg, $args)
DESCRIPTION
supersend
retourne le résultat de l'envoi du message $msg
et de ses paramètres à une instance ou à une classe dans le contexte de la superclasse de la classe de la méthode qui exécute supersend
.
$args
est un tableau dont le premier élément est l'instance ou la classe qui envoie et qui reçoit le message, e.g. $self
.
$args
peut contenir d'autres paramètres qui seront transmis avec $msg
.
supersend
sert généralement à appeler la version héritée d'une méthode qui est redéfinie par une sous-classe.
Appeler supersend
en dehors d'une méthode est un cas d'erreur qui déclenche une exception LogicException.
CODE
- function supersend($msg, $args) {
- $receiver=array_shift($args);
- return $receiver->sendsuper($msg, $args);
- }
supersend
extrait $receiver
de $args
et appelle la méthode sendsuper
de $receiver
avec en argument $msg
et tous les arguments restant dans $args
.
EXEMPLE
- namespace X;
- require_once 'So-o.php';
- defclass('X', null, 1, array('count'), array('value'), array('initialize', 'new', 'count'), array('free', 'init'));
La classe X compte ses instances dans la propriété de classe count. Elle redéfinit les messages de classe initialize et new et les messages d'instance free et init. Elle ajoute la propriété d'instance value et le message de classe count.
- function c_initialize($self) {
- return sendmsg($self, 'set', 'count', 0);
- }
c_initialize
initialise count à 0 quand la classe est construite.
NOTE : Le message initialize est automatiquement envoyé à une nouvelle classe par defclass
.
- function c_new($self) {
- $i=supersend('new', func_get_args());
- sendmsg($self, 'set', 'count', sendmsg($self, 'get', 'count') + 1);
- return $i;
- }
c_new
crée une instance de X en envoyant le message new dans le contexte de la classe Object, la superclasse de la classe X, puis incrémente count avant de retourner la nouvelle instance.
Remarquez comme la fonction PHP func_get_args
permet de fabriquer facilement l'appel à supersend
.
- function c_count($self) {
- return sendmsg($self, 'get', 'count');
- }
c_count
retourne le nombre d'instances de X.
- function i_free($self) {
- $count=sendmsg(sendmsg($self, 'class'), 'get', 'count');
- sendmsg(sendmsg($self, 'class'), 'set', 'count', $count - 1);
- supersend('free', func_get_args());
- }
i_free
décrémente count puis exécute le message dans le contexte de la classe Object.
Remarquez comment une méthode d'instance envoie un message à sa classe.
NOTE : Le message free est automatiquement envoyé à une instance qui n'est plus référencée.
- function i_init($self, $value=0) {
- supersend('init', func_get_args());
- sendmsg($self, 'set', 'value', $value);
- return $self;
- }
i_init
exécute le message init dans le contexte de la classe Object puis initialise value à la valeur du paramètre $value
du message.
NOTE : Le message init est automatiquement envoyé à une nouvelle instance par new.
$ php -a
php > require_once 'X.php';
php > echo sendmsg($X, 'count'), PHP_EOL;
0
php > $x1=sendmsg($X, 'new');
php > echo sendmsg($x1, 'get', 'value'), PHP_EOL;
0
php > $x2=sendmsg($X, 'new', 2);
php > echo sendmsg($x2, 'get', 'value'), PHP_EOL;
2
php > echo sendmsg($X, 'count'), PHP_EOL;
2
php > unset($x2);
php > echo sendmsg($X, 'count'), PHP_EOL;
1
php > quit
Commentaires