De PHP à Python et Ruby (en passant par C, Perl et Java)

Deux nouveaux langages sont venus tâter du polyglotisme.
J'ai aujourd'hui adopté...

Python Ruby
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 :

Java Perl PHP

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.

33 commentaires pour “De PHP à Python et Ruby (en passant par C, Perl et Java)”

  1. Kumi dit :

    Pas encore de boulet pour dire preum’s ? Nan ?
    Bon ben j’ouvre le bal alors :p

  2. Christophe971 dit :

    Un billet très intéressant, qui ne fait que confirmer les convictions de chacun d’entre nous (je crois).

    Mais plus que le manque de documentation de ruby (qui est en fait très documenté), il manque un truc génial que l’on a vu après des années de php, des années de C, et d’autres langages… des "mini-tutos", qui expliquent tout de suite comment faire X ou Y en trois ou quatre lignes. C’est ce genre qui faisait le bonheur de la période pré-blogs (@pages_persos multimania), quand tout le monde voulait expliquer l’html et le php à son voisin.

    J’èspère que cela ne trollera pas trop dans les commentaires, bon courage.

  3. Tournesol dit :

    Excellent article, cependant, j’ai une petite question subsidiaire : quid de la performance ? As-tu testé ?

  4. David, biologeek dit :

    Juste pour info, tu as codé le script en ruby avant ou après l’avoir fait en python ?

  5. Flipper dit :

    Je poserai les mêmes questions que Tournesol : "quid de la performance ? As-tu testé ?"

  6. Boris feat Styx dit :

    Dew, tu dors la nuit (des fois) ? ;)

  7. Samae dit :

    Oui, la performance ? En prenant en compte la facilité (un test subjectif mais interessant tout de même) …

  8. pouype dit :

    Très sympa ce billet. J’avoue ne pas avoir utilisé ce genre de technique, mais moi aussi j’ai voulu passé de php à autres chose. Et j’ai choisi Ruby (plutot que python) principalement pour son tout objet ;-).

    Pour ce qui est de la doc il y a http://www.ruby-doc.org/ qui regroupe pas mal de bon lien. Sinon au niveau francophone il y a rubyfr.org. D’ailleurs je prend bonne note du commentaire de Christophe971 pour essayer de faire quelque tuto simple ;-)

  9. Arnaud dit :

    pleac.sourceforge.net/ recense pas mal d’exemples du même genre (le même code dans différents langages)

  10. Neovov dit :

    Test très intéressant, merci Dew.

  11. Klamouze dit :

    Vraiment intéressant comme blog…

    Pour répondre à David, d’après ce que dis Dew, il a fait le Ruby après le Python. Il nous a indiqué la liste des sources dans l’ordre de leur création…

  12. Strass dit :

    BeautifulSoup existe pour Ruby aussi.
    Et, pour un programme aussi simple, j’aurais même opté pour un script shell !
    Un peu d’auto-promo : voir mon billet intitulé "Ruby vs Python" strasslab.net/blog/index….

  13. xk_liber dit :

    Très intéressant :)
    Moi aussi je veux bien connaître les performances ;)

    Hum.. sinon.. tu veux pas aussi le faire en Lisp, en Cobol ou, un poil plus moderne mais oublié probablement, en Rebol (langage sorti y’a 3 ans environ) ? ;) ;P

  14. Strass dit :

    Ah tiens, marrant que tes versions en Python et en Ruby se ressemblent pas mal, parce que quand on pratique un peu le Ruby, on perd vite l’habitude d’utiliser des boucles for pour énumérer des ensembles de données, mais on va beaucoup plus utiliser les "blocks" et les autres subtilités que propose Ruby. Ce qui donnerait alors quelque chose comme ça : strasslab.net/blog/share/…

  15. MonsieurN dit :

    J’en suis arrivé aux mêmes conclusions lors de mes différents tests ^^

    Ruby reprend quasi la même syntaxe pour les regex que Perl (la camparaison avec =~ est géniale je trouve), ce n’est donc pas exclusif à Perl.

  16. iwky911 dit :

    c’est juste une remarque comme ca mais tu dit: "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."

    Or si je ne me trompe pas, python aussi est tout objet (chaine, liste, tuples, dictionnaire, etc…)

  17. Christophe971 dit :

    Je vais répondre à Tournersol, Flipper et Samae à la place de dew, en citant un morceau de ce même post :
    "quel langage choisir pour écrire un script d’usage courant en un minimum de temps, **sans forcément prendre en considération les performances** ?"

    Dans ce genre de scripts vite fait, les performances n’ont aucun intérêt, même 0.10s passeront comme insignifiants. Donc n’essayez pas de chipotter, là n’est pas le but de ce post.

  18. Traxx dit :

    Billet trés trés intéressant, ça n’a pas du prendre 5 minutes tout ça ! Merci Dew pour tes impressions partagées !

    Le billet commence par décrire le besoin : "écrire un script d’usage courant en un minimum de temps, sans forcément prendre en considération les performances". On vise donc un cas particulier, récurent certe, mais particulier, et c’est bien, car faire des généralités est impossible, la solution dépendant toujours du besoin…

    Et en fin de billet : "L’avenir sourit donc aux langages de script interprétés et épaulés par un maximum de librairies – c’est une conclusion évidente.". Ce qui me gène un peu ici, c’est qu’on a l’impression d’une conclusion générale qui dirait en clair c, java, … c’est dépassé, il ne faut plus les utiliser c’est pas efficace. C’est évidemment faux ! On ne doit pas oublier que l’on est dans un cas particulier, ce que chacun ne va pas manquer de faire…

    Car si on veut être plus général, on doit évidemment se poser des questions, outre la performance qui revient toujours dans les discussions mais qui est en fait rarement le besoin prioritaire : est-ce adapté a des projets de grande taille ? La réutilisation ? La maintenaibilité ? l’évolutivité, …

  19. Narno dit :

    Et C# ?

    … avec Mono sous Linux ^^

  20. v dit :

    (mais mais mais, d’où elle sort, cette variable $numero, dans l’exemple php?)

  21. Fcom dit :

    Tu n’as pas pensé au Cobol ? C’est bon, je connais la sortie –> []

  22. Yvan dit :

    Super article, il confirme également ce que j’ai pu voir en testant les différents languages.

    Dommage que tu ai pas pu tester l’ASP ce qui pourrait donner une vision du PHP-ASP.

    A+

  23. Ju dit :

    Petite erreur dans la source PHP :
    $f=fopen($logfile,’r’);
    if($fquest) {

    Très bon billet, extrèmement intéressant, merci !

  24. denis dit :

    ouaip très intéressant. Merci pouype pour ces bons liens.

  25. Calimero dit :

    Le débat sur "quel langage" est sans fin… ca dépend du projet, du contexte, de l’existant, des gens… Maintenant il est indéniable qu’on arrive à faire certaines choses plus vite avec certains langages qu’avec d’autres…

    Comme dit, c’est un comparatif subjectif pour un contexte très précis.

    Je suis assez d’accord avec la conclusion toutefois: du scripting comme "glue" qui va s’appuyer sur des libraries en C/C++ histoire d’avoir une bonne souplesse sans trop souffrir en terme de performances.

    <troll>Java c’est pas dépassé, vu que ca a jamais servi à rien</troll>

    PS: man regex

  26. mkx dit :

    Très intéressante cette expérience.
    Pratiquant Python depuis deux ans, j’apprends Ruby…
    Faut pas rester monomaniaque !
    Voici un excellent comparatif sur ces deux langages :

    c2.com/cgi/wiki?PythonVsR…

    Ces deux langages étant si proches, il me semble que
    la pratique de l’un peut enrichir la compréhension de l’autre.

    à +, mkx.

  27. pythoniste dit :

    trés interessant mais.
    ne pas oublier que le script (programme) dois avoir d’autre caratérisques à prendre en compte
    exemple: est-il lisibe facilement pour facilier son amélioration?
    le langage peut-il suivre les nouveaux demande technologique?
    ……………

  28. Jerome dit :

    Il y a qd même un petit soucis :

    Quand vous faites de l’intégration sur un serveur Unix ou Linux pour un grand compte sans avoir le control du compte root, vous êtes souvent obligé d’utiliser les outils intégrés à l’OS. Et malheureusement tout nous ramène la plupart du temps aux scripts shell (ksh, bash … ), au Perl ou au Java. Même si dans quelques Linux on trouve du python.

    A quand l’intégration systématique de ruby aux systèmes UNIX ?
    il faudra peut être attendre la machine Parrot …

    Je cherche à faire un petit site dynamique sur un serveur Unix IBM (Aix) et même si j’ai droit à Perl, je n’aime pas beaucoup faire du CGI avec Perl !!!

  29. Arthur dit :

    Pour comparer des langages entre eux, encore faut-il les comparer dans les mêmes conditions :

    – maîtrise égale de langages (ce qui n’est visible pas le cas : exemple vous copier un titre potentiellement de 1024 caractères dans un buffer de 1000 caractères ! en C)
    – Utilisation de librairies pour tous les langages ou pour aucun.

    Votre test se résume à : j’utilise certains langages avec des librairies d’autres sans (sans doute parce que vous maîtrisez moins ces derniers) et vous arrivez à la conclusion logique que c’est plus rapide et plus fiable quand vous utilisez les librairies. Cela ne dit rien, en fait, des langages. Dommage, car l’idée de départ était bonne.

  30. Reboler dit :

    Dommage j’arrive après la guerre. C’est sympa mais que tout ces languages sont verbeux. Allez, my 2 cents en rebol:

    REBOL []
    all [
    title: select load/markup papaye.alsacreations.fr <title>
    title <> title: attempt [load %log.rebol.txt]
    probe "Difference"
    save %log.rebol.txt title
    send/subject
    [toto@rabbit.com tarzan@rabbit.com]
    reform ["New title:" title]
    "[Turborabbit] New title !"
    ]
    halt

  31. isatis dit :

    Certes, Rebol est concis, mais en l’occurence, ce script ne fait pas un certains nombres de choses que les autres font :

    – fallback divers;
    – verbosité de la sortie;
    – choix de l’expediteur;
    – predeclaration des variables à des fins de configuration et DRY.

    Sans compter qu’en ruby / perl / python on pourrait tout faire en one-liner, ça serait certes très concis mais pas lisible.

    Il faut comparer ce qui est comparable, rebol est très interessant, mais on est plus dans la circoncision que la concision là.

    Une comparaison juste serait avec quelque chose comme :

    import re, urllib as u, smtplib as s, email.MIMEText as m

    title, old = «  », «  »

    try :
    title = re.search(r »(.*?) », u.urlopen(« http://alsacreations.fr/ »).read()).groups()[0]
    old = open(‘log.py.txt’,’r’).readline()
    finally :
    if title != old :
    print « Difference »
    msg = m.MIMEText(« (Script python) New title !\n » + title)

    for a,b in ({‘Subject’:'[Turborabbit] New title’, « To »: ‘ »toto@rabbit.com’,
    « To »: ‘tarzan@rabbit.com’}).items():
    msg.add_header(a,b)

    smtp = s.SMTP()
    smtp.connect()
    for r in [« toto@rabbit.com », « tarzan@rabbit.com »] :
    smtp.sendmail(« dumbo@jumbo.com »,r,str(msg))

    with open(‘log.py.txt’,’w’) as f :
    f.write(title)

    On voit bien que Rebol reste incontestablement le plus concis, mais ce n’est pas le Goldorak de la courtitude.

    Un centime de plus donc.

  32. isatis dit :

    Evidement, pas pu m’empêcher de faire un version du script Pythonique, même si l’article date de 2006…

    http://pastebin.archlinux.fr/367323

    On gagne une dizaine de lignes et l’utilisation d’idiomes 100% Python.

  33. Reboler dit :

    Tiens je repasse comme ça…
    Houlaa, c’est passé en mode mauvaisefoititude je vois.
    Evidemment en utilisant telle ou telle librairie pour te mâcher le travail tu peux espérer seulement t’approcher en tout petit peu de la concision et de l’expressivité d’un programme Rebol.

    Mais avec ta démarche tu peux le faire en une seule ligne dans n’importe que language.
    écrit un programme A qui fait tout le boulot.
    Et un programme B qui simplement appelle A et tu as gagné !!! Tu l’as fait en une seule ligne.

    Ou alors comparons ce qui est comparable, et dans ce cas y’a pas photo.

Laisser un commentaire