Préambule
Cette année, parmi mes bonnes résolutions, j'ai décidé de me mettre (réellement) à Ruby, tant qu'au niveau personnel que professionnel. Pourquoi ? tout simplement qu'apprendre un langage c'est sympa, d'autant plus si ce dernier est prometteur.
Parmi les langages dits interprétés, dans ma vie professionnelle, j'ai pu m'exercer au développement PHP ou Perl (encore maintenant, cela peut m'arriver de taper quelques lignes), que ce fût pour le développement Web ou tout simplement le développement de scripts. Aussi, regarder vers d'autres langages- dynamiques (ie : vs. C#) - me paraît une démarche toute naturelle.
En plus d'apprendre un nouveau langage, Ruby semble être un candidat tout approprié, tant pour son élégance que pour sa puissance. A une époque, Python me titillait les doigts, mais, décision toute personnelle, la syntaxe me déplaisait, injuste et totalement partial, oui je sais - même si Django est en vogue comme framework MVC ou encore Google app engine ou encore ...Zope...non je plaisante , mais la syntaxe Python, non, vraiment, non, c'était au-dessus de mes forces. Un langage est souvent une affaire de coup de cœur.
Le meilleur moyen de prendre en main un langage est de mettre en application ce dernier - soit dans du scripting, soit dans une application Web, j'essaierai les deux.
Le réflexe serait de se diriger vers Rails. Bien qu'avoir lu le fameux Ruby on Rails et m'avoir testé à quelques essais Web, le framework m'a semblé extrême dans sa démarche.
Je m'explique :
- c'est un tout (ou rien), pas réellement le choix des briques logiciels utilisées : ORM, Javascript, moteur de rendu, bref un bloc monolithique,
- tout est convention (over configuration) et donc beaucoup d'implicite, notamment avec ActiveRecord, cela devient difficile avec un existant, même si on peut désactiver certaines choses,
- trop complexe à appréhender pour un novice malgré sa toute relative simplicité affichée, les erreurs affichées sont une catastrophe,
même si toutes ces objections paraissent être des mythes. Anyway, je pense que Rails reste trop uniforme, voire monoculture et ne donne pas suffisamment de liberté de choix au développeur...mais je changerai peut-être d'avis.
Installation de Ruby et de Merb
Procédons à l'installation de Ruby et de Merb. Il est évident que dans la vraie vie, tout ne se passe pas comme on le souhaiterait, voyons ce qu'il faut faire pour que cela se passe - à peu près - bien.
sous Linux
Ruby et Merb
Les versions installées :
- Ruby : 1.8.6
- Merb : 1.0.7.1, DataMapper : 0.9.9
L'environnement :
- Debian Etch
- Apache 2.x
Sous Linux, on préférera Ruby Entreprise Edition à la version officielle (sous Debian Etch, il demande au moins les paquet zlib1g-dev, libssl-dev). Pour les Debianiste, la version proposée de Ruby dans les sources officielles est la 1.8.5, autant dire trop vieille, on pourra passer par un backport pour obtenir une version plus récente.
REE est installé avec le répertoire racine /usr/local, tous les binaires seront donc installés sous /usr/local/bin
Installer les librairies sqlite et mysql pour Ruby : cela demande au préalable les entêtes pour chacun (SQLite 3 et MySQL 5) :
$ apt-get install libsqlite3-dev libmysqlclient15-dev
puis les gems :
$ gem install mysql sqlite3-ruby
on installe Merb :
$ gem install merb
Création d'une application pour test : $ merb-gen app test
lors de l'installation de Merb (1.0.7), la dépendance vers DataMapper semble être erronée, il faut modifier le fichier de l'application, test/config/dependencies.rb pour faire pointer vers la bonne version installée : dm_gems_version = "0.9.8" => dm_gems_version = "0.9.9"
In fine, on obtient l'environnement suivant :
$ gem environment RubyGems Environment: - RUBYGEMS VERSION: 1.3.1 - RUBY VERSION: 1.8.6 (2008-08-08 patchlevel 286) [i686-linux] - INSTALLATION DIRECTORY: /usr/local/lib/ruby/gems/1.8 - RUBY EXECUTABLE: /usr/local/bin/ruby - EXECUTABLE DIRECTORY: /usr/local/bin - RUBYGEMS PLATFORMS: - ruby - x86-linux - GEM PATHS: - /usr/local/lib/ruby/gems/1.8 - /home/od/.gem/ruby/1.8 - GEM CONFIGURATION: - :update_sources => true - :verbose => true - :benchmark => false - :backtrace => false - :bulk_threshold => 1000 - REMOTE SOURCES: - http://gems.rubyforge.org/
Serveur Web
Pour Merb, il nous faut un serveur Web, j'ai sélectionné Passenger du même éditeur que REE. Comme toujours, on fait simple :
les entêtes Apache2 sont nécessaires : $ apt-get install apache2-dev
$ gem install passenger
$ passenger-install-apache2-module
puis création d'un module passenger pour Apache2 dans /etc/apache2/mods-available/ :
cat > /etc/apache2/mods-available/passenger.load << EOF LoadModule passenger_module /usr/local/lib/ruby/gems/1.8/gems/passenger-2.0.6/ext/apache2/mod_passenger.so PassengerRoot /usr/local/lib/ruby/gems/1.8/gems/passenger-2.0.6 PassengerRuby /usr/local/bin/ruby EOF
on l'active :
$ a2enmod passenger & /etc/init.d/apache2 force-reload
L'exécution du site demande le rewriting d'URL : $ a2enmod rewrite
Sinon, à la place de Passenger ou en complément, il y a aussi le serveur mongrel que l'on installera avec gem install mongrel. Cela peut-être intéressant de l'installer car Merb a un mode interactif, pour debugguer une application, cela pourra aider.
sous Windows
Sous Windows, on installera Ruby avec la version RubyOn-Click Installer.
Installation de SQLite 3 :
$ gem install --version 1.2.3 sqlite3-ruby
Télécharger sur http://rubyforge.org/projects/dorb, le provider DM pour do_sqlite3 prendre la version x86-mswin32 puis l'installer :
$ gem install do_sqlite3-0.9.10.1-x86-mswin32.gem --local
En effet, le paquet par défaut sur rubyforge ne s'installe pas sous Windows car il demande une compilation de celui-ci :
$ gem install do_sqlite3 Building native extensions. This could take a while... ERROR: Error installing do_sqlite3: ERROR: Failed to build gem native extension. d:/ruby/bin/ruby.exe extconf.rb install do_sqlite3 checking for sqlite3.h... no *** extconf.rb failed ***
Il faudra également téléchargé la DLL sur le site de SQLite pour le mettre dans le répertoire d'installation de Ruby (d:\ruby\bin).
Au niveau serveur Web, choisissons Mongrel :
$ gem install mongrel
Testons notre installation
$ merb-gen app test $ cd test $ merb
devrait lancer le serveur Web sur le port 4000, cliquez sur http://localhost:4000
Testons un programme ruby
Je veux rechercher une URL dans des mails stockés sous forme de fichier, pour des mails en provenance d'une adresse précise. L'URL trouvée sera stockée dans un cache distribué memcached.
Nous avons besoin de 2 librairies : une pour lire un mail, une autre pour le client memcached.
TMail : $ gem install tmail
Memcached : téléchargement sur http://www.deveiate.org/projects/RMemCache du gem puis installation :
$ gem install Ruby-MemCache-0.0.4.gem
ou sinon il y a aussi http://tangent.org/552/libmemcached.html mais cela nécessite la librairie libmemcache qu'il faut compiler & co, pour ensuite installer le gem : $ gem install memcached
Le script maintenant :
#!/usr/local/bin/ruby require 'rubygems' require 'tmail' require 'memcache' spooldir = "/home/od/spool/*" from = "no-reply\@dummy.net"; expire = 4*60*60 memcache_options = { :c_threshold => 10_000, :compression => true, :debug => false, :readonly => false, :urlencode => false } CACHE = MemCache.new('localhost:11211', memcache_options) Dir.glob(spooldir).sort.each do |f| mail = TMail::Mail.load(f) if mail.from.include?(from) (prefix,domain) = mail.to[0].split(/\@/) url = mail.body.match(/(http:\/\/.+)/i) CACHE.set(prefix.downcase,url[0],expire) if url end end
c'est un réel plaisir ce langage, tellement expressif et naturel.
Astuces
Ne pas hésiter à utiliser le mode verbose de Merb : merb -V, cela permet de savoir les éventuelles erreurs lors du lancement.
Merb -i lancera l'application en mode interactif, ce qui signifie qu'on pourra taper des commandes directement pour simuler les accès ou obtenir des informations sur l'instance en cours.
Ressources
Installation de Passenger pour Merb.
Livres gratuits en PDF sur Ruby : Livre de 400 pages avec exemples à l'appui et solution Visual Studio SLN (pour une utilisation sous Ruby In Steel avec IronRuby) ou bien un livre de 80 pages du même éditeur.
Pour les développeurs C#, une série pour appréhender Ruby au travers de C# / IronRuby