Copyright (c) Martin Lafaix, 1996. Tous droits réservés. ©
Home | NetRexx | Une présentation

NetRexx

Quelques mots en introduction pour préciser que cet article ne remplace pas les divers documents en anglais présents sur le serveur dédié à NetRexx. L'objectif est plutôt ici de présenter quelques points particuliers, afin de démontrer l'intérêt de NetRexx.

NetRexx, qu'est-ce ?

NetRexx est un langage de programmation dérivé à la fois de REXX et de Java. NetRexx conserve la simplicité de REXX tout en incluant les spécificités de Java.

NetRexx est une alternative réelle face au langage Java. Il permet de créer des applets et des programmes Java beaucoup plus simplement. L'utilisation des classes Java est par exemple particulièrement simple, parce que vous n'avez à vous préoccuper des divers types de nombres ou de chaînes de caractères requis.

Où et comment obtenir NetRexx ?

NetRexx est disponible sur http://www2.hursley.ibm.com/netrexx/. Il est librement téléchargeable et fonctionne sur toute plate-forme implémentant Java.

NetRexx nécessite aussi la présence du kit de développement Java, ainsi que de ses modules d'exécutions, qui sont disponibles sur http://www2.hursley.ibm.com/javainfo/ pour OS/2 et AIX.

Le premier pas...

Commençons tout d'abord par nous débarrasser du sempiternel premier programme, le fameux « Hello World! ».

/* premier exemple : dire bonjour */
say 'Hello, Warped World!'

Le même programme en Java s'écrit par exemple comme suit.

/* la même chose en Java */
class hello
{
  public static void main(String args[])
  {
    System.out.println("Hello, Warped world!");
  }
}

Comme vous pouvez le constater par vous même, un programme NetRexx ne nécessite pas tout l'enrobage syntaxique de Java. Les programmes sont ainsi moins chargés, et donc plus lisibles.

Une deuxième constatation est que le programme NetRexx ressemble beaucoup à un programme REXX. En fait, tant qu'un programme ne fait pas appel à la toolkit Java, et qu'il ne définit pas de classes, il peut être très proche du même programme REXX.

Le deuxième pas...

Continuons notre programme précédent, de façon à le rendre interactif.

/* deuxième exemple */
say 'Bonjour, comment vous appelez-vous ?'
reponse = ask

if reponse = '' then
   say 'Vous ne voulez pas me parler ?  Alors je me tais, na !'
else do
   select
     when reponse = 'Chloé' then say 'Bonj... Êtes-vous arrangée par Duke Ellington ?'
     when reponse = 'Martin' then say 'Vous avez un très joli nom ! :-)'
   otherwise
     say 'Bonjour' reponse'. \0'
   end
   say 'Bonne journée à vous !'
   end

Comme précédemment, cela ressemble toujours beaucoup à REXX. Les seules deux différences étant d'abord la lecture de la réponse utilisateur (l'instruction PULL n'existe pas, et est remplacée par la variable ask) et ensuite le fait que les comparaisons par défaut ne font pas la différence entre majuscules et minuscules. Par exemple, vous pouvez indifféremment saisir « Chloé » ou « chloé ».

Les diverses structures de base sont également très proches (si ce n'est que l'instruction d'itération DO est remplacée par LOOP).

Toutes les opérations sur les chaînes de caractères REXX sont aussi présentes. La différence est qu'ici, NetRexx étant un langage à objet, on n'utilise plus la notation fonctionnelle --- comme LEFT('bonjour',3) --- mais la notation pointée --- i.e., 'bonjour'.LEFT(3).

Si vous avez observé attentivement le programme, vous vous êtes probablement interrogé sur la signification du '\0' final. C'est en fait pour supprimer le passage à la ligne lors de l'affichage du message, que l'instruction SAY ajoute normalement par défaut.

Si NetRexx ressemble par certains côtés à REXX, c'est néanmoins un langage différent, comme nous allons le voir maintenant.

De la méthode...

Les programmes présentés jusqu'ici étaient linéaires. Nous allons voir maintenant comment ajouter des méthodes statiques (ce qui est appelé fonction ou procédure en REXX).

/* troisième exemple */
say 'Quelle est votre taille, en centimètres ?'
taille = ask
say 'Vous mesurez plus de' pieds(taille) 'pieds et' pouces(taille) 'pouces.'
exit

method pieds(taille) static
  return taille % 30.48

method pouces(taille) static
  return (taille // 30.48) % '2.54'

Nous retrouvons ici les opérations arithmétiques REXX, et le fait qu'il n'y ait pas de différence a priori entre les chaînes de caractères et les nombres.

La déclaration des méthodes statiques, par contre, se distingue de celle des procédures/fonctions REXX en ce sens que les paramètres sont énumérés --- alors qu'avec REXX, on utilise ARG(n) ou PARSE ARG.

Le fait que l'on parle de méthode statique, au lieu de simple méthode tient au fait que les simples méthodes sont destinées à être appliquées à un objet --- comme la méthode LEFT évoquée plus haut --- alors que les méthodes statiques ne dépendent pas d'un objet précis, mais simplement de leurs arguments (et éventuellement d'une classe).

Dans ce troisième exemple, la lecture d'une mesure et sa conversion en d'autres unités a été faite de manière un peu artisanale. Ne serait-il pas souhaitable de pouvoir créer une nouvelle entité qui permette de représenter des longueurs ?

...avec classe !

Plus précisément, nous allons créer une nouvelle classe d'objets, Mesure.

/* quatrième exemple */
say 'Quelle est votre taille (par exemple, 6''3" ou 1,5m) ?'
taille = Mesure(ask)
say 'Vous mesurez' taille.enpieds 'soit' taille.enmetres
exit

class Mesure
  taille_en_cm

  method Mesure(t)
    if t.pos("'") > 0 then do
      parse t pieds "'" pouces '"'
      taille_en_cm = pieds * 30.48 + pouces * 2.54
      end
    else
    if t.pos(",") > 0 then do
      parse t metres "," centimetres "m"
      taille_en_cm = metres * 100 + centimetres
      end

  method enpieds
    return (taille_en_cm % 30.48)"'" || (taille_en_cm // 30.48) % 2.54 || '"'

  method enmetres
    return taille_en_cm % 100 || ',' || taille_en_cm // 100 || 'm'

Cette nouvelle classe d'objet est bien sûr rudimentaire, et ne comporte aucun contrôle d'erreur. Cependant, si le besoin s'en faisait sentir, nous pourrions ajouter des méthodes afin de permettre, par exemple, l'addition ou la soustraction de deux distances.

La classe Mesure définit trois méthodes : Mesure(), enpieds() et enmetres(), et un attribut, taille_en_cm.

La première méthode, Mesure(), est un constructeur parce qu'elle est de même nom que la classe et qu'elle est utilisée pour construire un nouvel objet. Lorsqu'une telle méthode est appelée, un nouvel objet appartenant à la classe Mesure est créé, et son état (ici constitué du seul attribut taille_en_cm) est initialisé en fonction de la valeur passée en argument lors de l'appel.

Les deux méthodes enpieds() et enmetres() sont utilisées pour afficher l'état de l'objet.

L'ensemble des attributs d'un objet déterminent son état. Ici, un objet de classe Mesure ne possède qu'un seul attribut, qui détermine donc complètement son état.

Il n'est pas possible d'accéder à l'état d'un objet sans passer par des méthodes de la classe de celui-ci. Par exemple, dans le programme principal --- avant l'instruction CLASS --- il est illégal d'utiliser l'instruction taille.taille_en_cm.

Dans certains cas cependant, vous pouvez vouloir explicitement modifier ce comportement, de sorte que l'attribut devienne accessible par tous (ou seulement par les classes dérivées). Similairement, vous pouvez modifier la visibilité d'une méthode, afin qu'elle ne soit visible que localement, ou par les classes dérivées.

On peut également définir des méthodes et des attributs statiques, comme nous l'avons vu précédemment. Une méthode ou un attribut statique est propre à la classe elle-même, et pas à une instance particulière d'icelle. On peut par exemple imaginer un attribut statique qui tiendrait compte du nombre d'instances créées, afin par exemple de limiter l'accès à une ressource.

De l'autre côté du miroir

La simplicité de NetRexx par rapport à d'autres langages comme Java tient au fait qu'il essaye au maximum de vous simplifier la vie. Par exemple, NetRexx ne connaît que les classes (et des instances de ces classes, les objet), et les classes ne comportent que des attributs et/ou des méthodes. Ainsi, même le premier exemple donné plus haut définit une classe et une méthode. Il est en fait compris comme :

/* le premier exemple re-visité */

class hello

  method main(argString=String[]) static
    say 'Hello Warped World!'

À chaque fois que cela est possible, NetRexx essaye de faire le travail à votre place. Dans le cas présent, puisqu'aucune classe n'avait été définie, il l'a fait pour vous. Même chose pour la méthode main() --- le point d'entrée de tout programme NetRexx.

C'est le même principe qui conduit au fait qu'il est rarement nécessaire de spécifier la classe des arguments des méthodes, ou, dans le cas des constructeurs, l'appel au constructeur de la superclasse et la valeur de retour.

Ce n'est après tout que la prolongation du principe qui fait que l'on ne programme plus que rarement en assembleur de nos jours. Si le compilateur peut faire le travail aussi bien que nous --- voire mieux --- pourquoi s'en priver ?

Et Java dans tout cela ?

Dans tout ce qui précède, le terme Java a été évoqué à plusieurs reprises. Cependant, quel est le rapport exact entre Java et NetRexx, vous demandez-vous ?

En fait le rapport est double. Dans un premier temps, NetRexx produit du code Java. Ce qui veut dire que toutes les applications créées en NetRexx peuvent s'exécuter sur toute plate-forme sur laquelle ont été installés les modules d'exécution de Java --- et ce bien sûr sans recompilation.

Le deuxième point est que NetRexx facilite énormément l'écriture des applications qui utilisent la toolkit Java, en s'occupant par exemple des conversions de types souvent nécessaires en Java.

Une chose doit tout de même être précisée : si vous souhaitez réaliser des applications complexes, avec des fenêtres et autres --- autrement dit, qui utilisent la toolkit Java --- vous devrez toujours apprendre l'utilisation de cet ensemble de classes. NetRexx vous dispense seulement de l'apprentissage du langage Java. Ce qui n'est pas un moindre mérite.

Conclusions

NetRexx est un langage qui, tout en préservant la simplicité de REXX et sa philosophie, ajoute l'accès au monde prometteur de Java.

En fait, si l'on ne s'en doutait pas déjà, NetRexx montre à quel point est importante la qualité de la conception d'un langage, et ne peut que faire regretter le choix de C++ comme modèle pour le langage Java. La bonne nouvelle est que, comme le langage Java n'apporte strictement rien de plus, on peut en toute tranquillité l'ignorer.


Martin Lafaix