De PHP à Python et Ruby (en passant par C, Perl et Java)
Jeudi 1 juin 2006 | GeneralDeux nouveaux langages sont venus tâter du polyglotisme.
J’ai aujourd’hui adopté…


Python et Ruby
… pour tenter de répondre à la (trollesque) question suivante : quel langage choisir pour écrire un script d’usage courant en un minimum de temps, sans forcément prendre en considération les performances ? La logique voudrait que l’on s’oriente vers un langage interprété, faiblement typé, fourni avec de nombreuses librairies pour se faciliter la vie et écrire un minimum de lignes.
Sachant aussi que beaucoup de monde est familiarisé à PHP, quelle est la facilité de transition vers ces langages ? Ou encore, lorsqu’on ne connaît rien : vers lequel s’orienter pour débuter ?
Je suis parti, pour cette comparaison totalement subjective, d’un script PHP écrit en 5 minutes, et je l’ai traduit en deux autres langages que je connaissais pas encore : Python, et Ruby qui est à la mode actuellement grâce à Ruby On Rails.
Par curiosité, je l’ai aussi écrit en Perl, Java et C. Mais pas d’assembleur pour sauver un minimum de vie sociale (en évitant aussi tout ce qui est Eiffel, Smalltalk, Fortran, Lips ou Caml, on n’est pas des bêtes). (Que celui qui a dit Promela sorte).
Le but est donc d’écrire le même script dans tous ces langages. Celui-ci va devoir :
- Récupérer une page xhtml distante via http
- Partir à la recherche du contenu de la balise <title>
- Le comparer au dernier <title> mémorisé dans un fichier
- Envoyer un mail d’avertissement à une liste de destinataires s’il y a eu modification
- Ecrire le nouveau <title> dans le fichier
Ceci va donc permettre de « tester » les quelques points suivants :
- syntaxe générale du langage (blocs, structures de contrôle, overhead en libs)
- types (chaînes de caractères, listes et tableaux)
- facilité d’emploi des PCRE (expressions régulières)
- facilité d’emploi des connexions
- lecture et écriture de fichiers
- efficacité et facilité d’utilisation des modules préfabriqués (http/smtp) s’ils existent
D’autres particularités auraient aussi pu être évaluées : la connexion vers des bases de données (MySQL), le support du XML, la POO pure, les fonctions, etc. Mais ce test doit rester simple et équitable (autant qu’il puisse l’être). Chacun de ces langages a ses spécificités et son usage de prédilection. Un seul critère peut être éliminatoire dans le choix d’un langage. C’est donc là un cas particulier qui est mis en valeur, et non pas un benchmark (on n’écrit pas de moteur 3D en php).
Il se peut que chaque code n’ait pas été écrit comme il pourrait l’être idéalement. Premièrement parce que ça fait un moment que je n’ai plus fait de Java, que le C n’est pas mon compagnon de chambrée favori, que j’ai découvert Python et Ruby sur le moment, et qu’il y a des dizaines de façons d’arriver à ses fins. Une autre question subsidiaire vient alors s’ajouter : s’oriente-t-on directement vers la meilleure syntaxe ?
Voici les sources obtenues, dans l’ordre de leur création :


Résultats et impressions (liste non exhaustive) :
Python et Ruby sont proches, ce qui est compréhensible car Ruby reprend des concepts de Python et Lisp. Ruby a l’avantage d’être entièrement orienté objet.
PHP, Python et Ruby sont bien fournis en libs HTTP et SMTP/mail. Lorsqu’on cherche à développer les mêmes types de communications dans les autres langages, il faut creuser bien plus profond que l’emploi de fonctions standard. Il existe BeautifulSoup pour Python, qui permet de parser du html très rapidement. Je ne l’ai pas utilisé ici, mais deux lignes auraient été gagnées.
Evidemment en C, il ne faut pas s’attendre à grand chose : pour récupérer la page et envoyer un mail j’ai exploité les sockets en dur (protocoles HTTP et SMTP).
Même chose pour Java : au point de vue HTTP une petite pirouette grâce à une classe existante, mais pour l’envoi des mails SMTP reste favori (tandis que javamail serait exploitable, mais son adjonction au projet eût été lourd et long).
Autre évidence : lorsqu’on gère soi-même ce type de connexion, on ne peut gérer toutes les erreurs (du moins, on n’en prend pas le temps). Il y a donc, par défaut, moins de protection à ce niveau-là en C et en Java. Ce qui conduit à négliger la stabilité et la sécurité dans des langages de plus bas niveau lorsqu’on manque de temps.
Perl a toujours pour lui la force des expressions régulières et une écriture compacte. Cependant, il n’y a par exemple pas de fonction trim, d’où l’écriture nécessaire d’une pirouette :
my $str = shift; $str =~ s/^\s+//; $str =~ s/\s+$//; return $str; }
En ce qui concerne HTTP et SMTP, les modules libwww pour HTTP et libmime-lite-perl pour SMTP sont d’une utilisation fluide comme dans les autres langages de script, cependant ils ne sont pas nécessairement livrés avec Perl. Il faudra donc peut-être les installer manuellement, après avoir deviné leur existence.
En C, il n’y a pas de facilité pour les regexp. Ce qui conduit au traditionnel jonglage avec les pointeurs. C’est un véritable frein lorsqu’on est amené à effectuer des manipulations autres qu’une simple concaténation, au contraire de PHP/Python/Ruby qui sont vraiment orientés vers la manipulation de chaînes. Il n’y a par exemple là aussi pas de fonction trim, d’où :
found = strlen(last_title)-1; while(last_title[found] == '\n' || last_title[found] == '\r') last_title[found--]=0;
Ca n’a rien de sorcier, mais ça use le clavier.
Conclusion : il m’a fallu environ 5 minutes pour le script PHP, 40 minutes pour Python, 25 minutes pour Ruby, 15 minutes pour Perl, et beaucoup plus pour le code C et Java.
Pour établir un classement – résultat prévisible dès le départ – en terme de facilité : PHP = Ruby > Python > Perl >> Java >> C. Mais là aussi, il s’agit d’un avis personnel, il appartient à chacun de moduler selon ses propres compétences et habitudes.
L’avenir sourit donc aux langages de script interprétés et épaulés par un maximum de librairies – c’est une conclusion évidente. Il est cependant dommage que la doc de Python soit soviétique, et que celle de Ruby soit encore en devenir. Lorsqu’on a l’habitude de la documentation PHP traduite dans toutes les langues, avec un moteur de recherche performant, un bon niveau de détails sur toutes les fonctions, des commentaires pertinents et des exemples, ça change.
Sources : Python Global Module Index, Dive into Python, Rubycentral : Class and Library Reference, Rubycentral : Programming Ruby, et tout ce qui est doc Java API par Sun, man, rtfm et stfw.
Accueil


