Oupsnow, de Merb à Rails. Alors que je finissais une …">

Shiny happy people coding

Codons avec le sourire

Oupsnow de Merb à Rails

| Comments

Dernièrement, j’ai fini par me décider de migrer Oupsnow, de Merb à Rails.

Alors que je finissais une migration de SQL à MongoDB, j’en entame une nouvelle. Celle-ci beaucoup plus profonde.

La raison de ma migration ?

Rails 3. En effet, depuis Décembre 2008, soit presque un an, Merb s’est figé. Certain me diront que la communauté Merb est en train de revivre et c’est tout à fait vrai. J’en suis même ravi. Mais Merb a pris un immense retard en presque un an. Même si Rails n’a pas vraiment avancé dans sa version stable, sa version Edge a elle énormément avancée.

Voulant toujours tester les nouvelles technologies en Ruby, je voudrais tester Rails 3. Mais aucun système n’existe pour passer de Merb à Rails 3. Un rapide test m’a montré que la différence était par contre minime entre Rails 2.3.x et Rails 3. La migration de Rails 2.3.x à Rails 3 en sera donc d’autant plus simple.

Voulant vraiment sortir une version stable le plus vite possible, j’ai donc pris la décision de migrer Oupsnow vers Rails 2.3.x pour ensuite migrer sur Rails 3 pour cette fois sortir une version de Oupsnow compatible Rails 3.

Oupsnow devient donc un projet Rails/MongoMapper et non plus Merb/DataMapper comme sa dernière version. Toute aide est bien-sûr la bienvenue.

English translation

RabbitMQ ne marche pas avec Mac OS ?

| Comments

Il y a quelque semaine, alors que je me remettais tout simplement à l’utilisation de RabbitMQ, j’ai eu un gros problème. Alors qu’il faut configurer les vhost et les utilisateurs de RabbitMQ, impossible de contacter mon service rabbitMQ avec la commande rabbitmqctl. Prévoyant une migration vers Mac OS Snow Leopard et n’ayant pas un besoin urgent de RabbitMQ, j’ai repoussé la recherche du problème.

Mais voilà, maintenant que je suis sous Mac Os Snow Leopard, j’ai réinstaller RabbitMQ pour le réutiliser à nouveau. Et là, surprise toujours le même soucis. Après de longue recherche, je viens enfin de trouver la cause, le hostname.

Que faire si votre noeud de contrôle rabbitMQ n’arrive pas à discuter avec le noeud maitre ?

Très simple, faite un simple hostname -s et ajouter ce hostname en concordance de l’ip 127.0.0.1 dans votre fichier /etc/hosts. Ça y est tout fonctionne. C’est parfois tellement simple la résolution d’un problème.

English translation

Le logger ruby avec son bloc

| Comments

Alors que je m’amusais à étendre le Logger de base de Ruby, j’ai découvert que l’on pouvait utiliser le Logger comme ci-dessous :

Logger.debug { “My object is #{self.map(&:id)}” }

Par défaut, on l’utilise en fournissant une string en paramètre comme ceci : Logger.debug("My object is #{self.map(&:id)}").

La différence entre ces deux écritures ?

La première permet d’éviter d’évaluer la chaine qui sera loggé si elle n’en a pas besoin. Contrairement à la deuxième qui sera toujours évaluée même si vous ne la loggez pas. Ainsi le temps de traitement pourrais s’en faire ressentir.

Grâce à ça, on peux facilement éviter les fameux :

Logger.debug(“My object is #{self.map(&:id)}”) if Logger.level == Logger::DEBUG

En effet, ce genre de code est très fréquent en Java, pour gagner un petit peu en performance sans perdre ses logs.

Pourquoi Rspec au lieu de Test::Unit?

| Comments

Dernièrement, on m’a posé la question toute bête :

Pourquoi Rspec au lieu de Test::Unit ?

C’est vrai que je suis un adepte de Rspec et que je n’utilise que ça si c’est possible. mais je n’ai jamais expliqué ici clairement ce qui me pousse dans ce choix. Donc voici un résumé très bref de mon choix.

Les formateurs

Une des options méconnues de Rspec est la possibilité de définir son formateur. Il existe ainsi plusieurs formateurs base. On peux ainsi avoir un retour direct sous format HTML ou text avec les points ( classique avec Test::Unit). Mais certain formateur peuvent aussi calculer le temps que dure un exemple. Ainsi nous avons une facilité de détection des test les plus lent pour les refactorer et essayer d’améliorer le temps de réalisation de ses tests. Dans ce sens, j’ai moi même créer mon propre formateur Rspec.

Les tests partagés

Rspec dispose d’une possibilité sous estimés, les tests partagés. En effet, on peux définir certain jeux de test comme “partageable” on a ainsi la possibilité de les incorporer facilement dans divers tests. C’est une fonction vraiment pratique dans le cadre de test fonctionnel principalement. Plus besoin de copier/coller son code. :)

Compatibilité Test::Unit

Le passage a Rspec est assez aisé de part sa compatibilité avec Test::Unit. En effet, si vous n’êtes pas familier ou que vous n’aimez pas la formalation my_array.should be_empty, rien ne vous y oblige. Vous pouvez tout à fait utiliser la syntaxe Test::Unit assert my_array.empty?. La migration s’en trouve très largement aisée.

l’OSDC.fr 2009, j’y serais

| Comments

Le 2 et 3 Octobre aura lieu en première française, un rassemblement de codeur d’environnement différent, l’OSDC.fr. Cette conférence est organisé par les associations françaises de Ruby (RubyFrance), Python (AFPy) et Perl (Mongueurs de Perl). Mais ce ne seront pas les seuls langage qui seront présenté. On peux ainsi trouver des sujets sur du PHP.

En tout cas je suis très heureux de pouvoir y présenter une petite conférence sur Cucumber. J’espère vous y retrouver.

Open-notification v0.1.0 est sortie

| Comments

Il y a maintenant un mois, j’ai commencé à jouer avec nanite. Pour essayer un peu cette technologie, j’ai réaliser une mini application en sinatra et un agent nanite qui envoi des notifications par Jabber.

De fil en aiguille, le code s’est agrémenté et est surtout passé à Merb avec un système de persistance en CouchDB.

L’idée de base est extrêmement simple, gérer plein de notification de tous type. Il existe déjà ce genre de système comme messagepub. Mais là ca sera open source.

Open notification sort donc en version 0.1.0 pour sa première version. Le code sera mis sous licence AGPLv3. Il est composé d’un agent nanite qui gére l’envoi des notifications jabber et d’une application avec Merb/CouchDB.

La méthode de déploiement est assez compliqué je l’avoue car il n’y a aucune documentation. Cela arrivera dans les prochaines versions.

Une version complête est utilisable par tout un chacun sur open-notification.com. Ce service n’a pour l’instant aucune pérennité. Mais on verra dans le futur ce que ca donnera.

DM-sweatshop, le petit truc en plus par rapport à Factory Girl

| Comments

En jouant avec Oupsnow, j’ai découvert une astuce sur DM-sweatshop qui est vraiment génial. Aucun exemple n’indique ça et pourtant, c’est selon moi révolutionnaire et même un atout face à Factory Girl.

dm-sweatshop

Pour ceux qui ne le savent pas dm-sweatshop est un gem de génération de donnée, inspiré de Factory Girl.

Factory Girl a été conçu pour éviter les fixtures dans Rails. Il a aussi l’avantage de permettre une meilleure vue des données présentes dans sa base de donnée durant son test. Je conseille tout à fait son utilisation et migre progressivement tous mes tests à l’utilisation de ce genre d’outil.

dm-sweatshop est le Factory Girl dédié à DataMapper, même si Factory Girl peux tout à fait être utilisable avec DataMapper.

Son petit plus

dm-sweatshop contrairement à Factory gril, génére un Hash d’attribut, qu’il surcharge avec les données fournis et génére un objet à partir de ce hash. Ceci entraine par exemple, l’impossibilité d’utiliser les méthodes d’association, il faut directement associer les identifiants.

Mais là où est son petit plus est que justement à cause de cette génération d’un Hash, il y a un Proc qui est généré et rien n’empêche de mettre du code ruby pour générer d’autre objets ou récupérer des objets déjà existant. On peux ainsi écrire l’exemple suivant :

Member.fixture { user = User.first(:login.not => ‘admin’) || User.gen! project = Project.first || Project.gen! not_project_id = [] while project.has_member?(user) not_project_id << project.id project = Project.first(:id.not => not_project_id) || Project.gen! end { :user_id => user.id, :project_id => project.id, :function_id => (Function.first ? Function.first.id : Function.gen.id),} }

Dans cette exemple, je crée un objet Membre qui est la liaison entre un Projet et un User. Mais au préalable, j’ai récupéré et créé des éléments Projet et User si rien n’existait.

Grâce à dm-sweatshop, c’est enfin fini, les problèmes de multiples liaisons qui avec Factory Girl ne peuvent être contourné (d’après mon expérience en tout cas) ce qui entrainait la création de méthode complète pour créer tout ça. Désormais tout est au même endroit.

Je ne saurais donc vous encourager à utiliser dm-sweatshop sur tout projet DataMapper à la place de Factory Girl.

Observer Vs Callback

| Comments

Il y a peu au boulot, j’ai indiqué ma désapprobation des Observeurs face au Callback. Je vais donc le coucher ici par écrit mon sentiment.

L’Observeur

Dans Rails, il y a au premier abord une fonctionnalité vraiment intéressante. L’Observeur. Grâce à lui, on peux définir une classe qui vérifie le comportement d’un model et effectue certaine action suite à ses observations. Il permet d’ajouter des événements avant/après l’enregistrement, la mise a jour ou la destruction d’un model.

Pour mettre en place un observeur, il suffit de créer une classe héritant de ActiveRecord::Observer, mettre son code dedans et la définir comme observeur dans le fichier environment.rb. Rien de plus simple et ça marche très bien.

Le Callback

Mais Rails a déjà intégré dans ses models, les fonctions de callback utilisé par le observeur. En effet, on peux tout à fait définir N action after_save ou before_create. Ces méthodes seront appelés à l’événement voulu.

Mais que choisir ?

C’est là où je dis que le callback est plus intéressant que l’observeur. En effet, un callback fait exactement la même chose qu’un Observeur. Mais lui au moins on sait qu’il est là. En ouvrant la classe on découvre le callback. Pour détecter un Observeur, il faut regarder les fichiers de config de Rails et ouvrir une à une les classes Observeurs.

Même le cas du nombre de ligne n’est pas réel car il est tout à fait possible de sortir ses callbacks dans des modules. De même pour une réutilisation sur plusieurs classes. Le module le permet sans problème.

Personnellement, je n’ai jamais constater un seul cas où l’observeur avait plus d’intérêt que des callback. Si vous en trouvez, je suis vraiment curieux.

Cucumber>=0.3.4 et Merb. La dure cohabitation

| Comments

Depuis la sortie de Cucumber 0.3.4 et pour les versions suivantes, une grosse modification dans Cucumber impose de changer un peu son utilisation avec Merb. En effet, si on peux lire dans le History.txt de Cucumber :

** IMPORTANT UPGRADE NOTES FOR RAILS USERS ** Running Cucumber features in the same Ruby interpreter as Rake doesn’t seem to work, so you have to explicitly tell the task to fork (like it was doing by default in prior versions). In lib/tasks/cucumber.rake: Cucumber::Rake::Task.new(:features) do |t| t.fork = true # Explicitly fork t.cucumber_opts = %w{–format pretty} end (If you run script/generate cucumber this will be done for you). Alternatively you can omit forking and run features like this: RAILS_ENV=test rake features However, setting the RAILS_ENV is easy to forget, so I don’t recommend relying on this.

Cela est aussi vrai pour les utilisateurs de Merb. En général pour les utilisateurs de Merb, vous avez utilisé le plugin merb_cucumber de Roman. Hélas celui-ci a un générateur incomplet à l’heure actuel. En effet, la tâche rake features n’utilise pas les bonnes options pour cucumber.

Après un long et rude combat avec cucumber, j’ai fini par trouver les options adéquates pour avoir le même comportement que pour les précédentes version de Cucumber. Pour voir un exemple en “live” sur une application, vous pouvez regarder mon commit sur Oupsnow. Sinon, j’ai forké le merb_cucumber de roman, et ajouter un patch pour permettre l’utilisation de Cucumber 0.3.4 et plus

EDIT : Mes modifications de merb_cucumber ont été intégré dans la branche de Roman

English translation