Vivre avec Rails Edge #17
Depuis le début, je suis les news de Chu Yeow concernant les nouveautés intégrés à Rails dans sa version de développement. J'ai décidé d'essayer de vous les traduire régulièrement ici.
Traduction de la news #17
Peu de chose se sont passé cette semaine sur Edge Rails. Il semblerait que nous aillons un nouveau membre dans le Rails core, Joshua Peek. Le nouveau bug tracking de Rails sur Lighthouse est pret à utiliser, donc vous pouvez y soumettre vos patchs et rapport de bug dessus.
Le rapport de cette semaine couvre les changements entre le 14 Avril 2008 et le 20 Avril 2008 (Jour correspondant à l'enregistrement de Rails Envy podcast).
caches_page conditionel
The caches_pages peuvent prendre une option :if pour indiquer quand une pave peux être vraiment caché via une Proc. Vous pouvez maintenant faire ceci par exemple:
caches_page :index, :if => Proc.new { |c| !c.request.format.json? }
Cela met votre index en cache uniquement si le format de la requête n'est pas du JSON.
Cette fonctionnalité a été ajouté par Paul Horsfall.
Révision concernant cette fonctionnalité: http://github.com/rails/rails/commit/14a40804a29a57ad05ca6bffbe1e5334089593a9
Nouvelle ActionView::TestCase pour tester les helpers des vues
Rappelez vous comment vous pouvez actuellement utiliser les classes TestCase spécialisé pour tester les classes Controllers et ActionMailer (en)? Désormai s vous pourrez faire la même chose pour vos helpers de vues Rails avec la nouvelle classe ActionView::TestCase.
Voici un petit exemple:
module PeopleHelper def title(text) content_tag(:h1, text) end def homepage_path people_path end end class PeopleHelperTest > ActionView::TestCase def setup ActionController::Routing::Routes.draw do |map| map.people 'people', :controller => 'people', :action => 'index' map.connect ':controller/:action/:id' end end def test_title assert_equal "<h1>Ruby on Rails</h1>", title("Ruby on Rails") end def test_homepage_path assert_equal "/people", homepage_path end
Remercions Josh Peek pour cette jolie petite amélioration..
mem_cache_store de ActiveSupport::Cache accepte des options
Même si Memcache-client a été ajouté récement à ActiveSupport, on ne pouvait pas spécifié toutes les options de configuration derrière l'ip du serveur memcache. Maintenant vous pouvez passer beaucoup plus d'options comme ceci:
config.action_controller.fragment_cache_store = :mem_cache_store, 'localhost', { :compression => true, :debug => true, :namespace => 'foo' }
Ce patch est de Jonathan Weiss.
Révision concernant cette fonctionnalité: http://github.com/rails/rails/commit/9e1d506a8cfedef2fdd605e4cbf4bf53651ad214
[...]Migration basée sur l'heure utc et plus incremental
Depuis la revision r9122, les migrations de Ruby on rails ne sont plus incrémentale comme précédemment. En effet, elles sont désormais basé sur le temps UTC. Cette évolution a comme principale intérêt d'éviter les problèmes de conflits entre différentes branches de développement grâce à un prefix unique.
Désormais lors de la création d'un fichier de migration vous aurez ainsi ceci :
$ ./script/generate migration create_user create db/migrate/20080422122512_create_user.rb
Pour compléter cette évolution, il y a eu l'ajout de 2 nouvelles tâches
rake. rake db:migrate:up et rake db:migrate:down. Il faut adjoindre à ces tâche la la variable VERSION étant le numero de la VERSION a ajouter(up) ou
enlever(down). Les versions peuvent ainsi être ajoutées ou supprimées
indépendamments.
On pouvait avoir cette fonctionnalité dans la version 2.0 de rails avec le plugin enhanced migrations plugin
[...]Gestion des dépendances des gems directement dans Rails
Suivant toujours les évolutions de Rails dans sa version edge, je vais commencer une série de billet pour vous informer de quelques nouveautés pour Rails 2.1. Je trouve ces évolutions assez sympathiques.
La première que je vais vous montrer est la gestion des dépendances de gems
On pourra définir directement dans le fichier d'environnement de Rails les gems qui sont en dépendance de notre application. On peux ainsi y définir le nom, la version et même le dépôt de notre gems. Très pratique pour gérer ses dépendances. Plus besoin de forcement, copier les gems directement dans ton /vendor/. Voici un exemple de configuration :
Rails::Initializer.run do |config| # Necessite la derniere version du gem HAML config.gem "haml" # Necessite la version 0.2.3 de chronic config.gem "chronic", :version => '0.2.3' #Necessite le hpricot a partir d'un depot specifique config.gem "hpricot", :source => "http://code.whytheluckystiff.net" # Necessite un gem particulier qui necessite une ligne differente de require # I.e. Si vous loader normalement le gem avec require 'aws/s3' au lieu de # require 'aws-s3' alors vous devez le specifier dans l'option :lib config.gem "aws-s3", :lib => "aws/s3" end
Avec cette fonctionnalité de nouvelles tâches rake ont été ajoutées :
- rake gems:install => permet d'installer tous les gems nécessaire
- rake gems => permet de lister tous les gems nécessaires à l'application
- rake gems:unpack => Copie tous les gems en dépendance dans le dossier /vendor/gems
- rake gems:unpack GEM=hpricot => Supprime le gems hrpicot du dossier /vendor/gems
- rake gems:build => construit les gems qui ont des extensions native.
Thin, le buzz qui se justifie
C'est quoi Thin ?
Depuis maintenant 3 mois seulement un nouveau gem est apparu comme webserver. Sa logique est simple. Prendre tout ce qu'il y a de meilleur partout, de compiler tout çà et d'en faire un meilleur produit. Ce gem, c'est Thin. Il se dit "Yet Another WebServer". Je pense que le titre est en référence à YARV. Mais je n'en ai aucune preuve.
Depuis la version 0.7.0 de thin, le buzz a pris de l'ampleur sur les bienfaits de ce WebServer. Étant un peu aventurier, j'ai décidé de tenter l'aventure. J'ai migré mes 3 applications de mongrel_cluster vers Thin. Voici donc comment faire cette migration car il n'y a rien de plus simple.
Installer Thin
Il faut déjà installer le gem thin
#gem install thin
Le meilleur moyen pour lancer les commandes de lancement de Thin, il faut allez dans le répertoire de son application Rails. Dans ce répertoire, faire :
$thin config -C config/thin.yml
Avec cette commande thin va préparer un fichier de configuration complet il ne vous restera plus qu'à le modifier. J'ai mis ce fichier dans config/thin.yml pour être homogène avec mongrel_cluster. Il n'y a aucune obligation de nomage ou d'emplacement. Le fichier de base est du type suivant :
--- pid: tmp/pids/thin.pid log: log/thin.log port: 3000 max_conns: 1024 timeout: 30 environment: development max_persistent_conns: 512 chdir: /var/rails/typo-5-0-stable address: 0.0.0.0
Il ressemble ainsi très fortement au fichier de mongrel_cluster.yml. Il ne reste plus qu'a le modifier pour qu'il fasse ce que l'on souhaite. En général, on modifie le port et l'environnement. Ensuite, on peux définir le nombre d'instance de thin dédiés à cette application. Pour cela on a juste à rajouter la clé servers: et donner le nombre d'instance. Mon fichier est ainsi devenu :
--- pid: tmp/pids/thin.pid log: log/thin.log port: 44000 max_conns: 1024 timeout: 30 environment: production max_persistent_conns: 512 chdir: /var/rails/typo-5-0-stable address: 0.0.0.0 servers: 2
Enfin pour démarrer ou arreter ces instances, rien de plus simple.
démarrage :
$ thin start -C config/thin.yml
arrêt :
$ thin stop -C config/thin.yml
Et maintenant l'intérêt ?
Intérêt de thin
Au niveau de la mémoire, il n'y a pas vraiment de différence entre mongrel et thin. Ils utilisent a peu près la même mémoire d'après ce que j'ai pu constater. Par contre, au niveau de la vitesse de réponse, thin est un peu plus rapide. Ainsi voici les résultats d'un benchmark rapide que j'ai réalisé sur ma dédibox.
Pour mongrel
hello:~/$ ab -n 1000 -c 10 http://dev.shingara.fr/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking dev.shingara.fr (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests
Server Software: nginx/0.6.26
Server Hostname: dev.shingara.fr
Server Port: 80
Document Path: /
Document Length: 4640 bytes
Concurrency Level: 10
Time taken for tests: 81.920747 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 4995000 bytes
HTML transferred: 4640000 bytes
Requests per second: 12.21 [#/sec] (mean)
Time per request: 819.207 [ms] (mean)
Time per request: 81.921 [ms] (mean, across all concurrent requests)
Transfer rate: 59.53 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 36 38 1.5 38 76
Processing: 94 778 726.4 644 4108
Waiting: 92 774 723.3 641 4106
Total: 131 816 726.4 681 4146
Percentage of the requests served within a certain time (ms)
50% 681
66% 1273
75% 1344
80% 1382
90% 1669
95% 1924
98% 2634
99% 3011
100% 4146 (longest request)
Pour thin
hello:~/$ ab -n 1000 -c 10 http://dev.shingara.fr/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking dev.shingara.fr (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests
Server Software: nginx/0.6.26
Server Hostname: dev.shingara.fr
Server Port: 80
Document Path: /
Document Length: 4640 bytes
Concurrency Level: 10
Time taken for tests: 67.245564 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 4986008 bytes
HTML transferred: 4646330 bytes
Requests per second: 14.87 [#/sec] (mean)
Time per request: 672.456 [ms] (mean)
Time per request: 67.246 [ms] (mean, across all concurrent requests)
Transfer rate: 72.41 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 36 44 133.9 38 3035
Processing: 93 621 462.3 518 1946
Waiting: 91 548 389.6 473 1665
Total: 132 666 483.9 561 4278
Percentage of the requests served within a certain time (ms)
50% 561
66% 878
75% 1017
80% 1098
90% 1309
95% 1580
98% 1703
99% 1795
100% 4278 (longest request)
Ca veux dire quoi ?
Il y a une petite avance pour thin qui permet de faire 14,87 requêtes par seconde contre 12,21 requêtes pour mongrel. Tout cela avec 10 instances simultanés et un total de 1000 requêtes. Mais après tout thin n'a que 3 mois. Il est encore jeune et n'a pas de version 1.0. Ça devrait pouvoir encore s'améliorer.
Coté parano ?
Je n'ai pas encore pu tester la stabilité de thin. En effet, on peux se demander à juste titre si il est vraiment stable. Pour cela il faudra attendre.
[...]quand la vue modifie son layout
Cas d'utilisation
Dans l'administration de Typo, en fonction du controller appelé, voir de l'action, il faut modifier la partie indiquant le sous-menu. On a donc 3 possibilités pour réaliser cette partie dynamique.
- Mettre la partie variable directement dans la vue et l'enlever du template.
- Mettre les informations directement dans le controller ou l'action et c'est cette information qui sera lu par le template
- Utiliser content_for directement dans la vue en utilisant le yield dans le template
Bien sûr la meilleur méthode est la troisième. Mais je vais expliquer pourquoi et comment on peux mettre en oeuvre.
Mettre la partie variable directement dans la vue et l'enlever du template
Cette méthode est de loin la plus simple qui soit. On sait que notre partie n'est pas toujours affiché pour le layout indiqué, donc on la met pas dans le template. Mais voilà, si on a du code entre notre partie dynamique et le vrai contenu de notre vue, on a pas le choix il faut dupliquer cette partie et ainsi on se retrouve à faire plein de copier coller et comme on sait le copier coller c'est pas DRY. Il faut donc essayer de proscrire cette méthode. Le cas le plus horrible est bien sur la modification de la partie que vous avez mis dans chaque vue et ceux sur vos 100 vues. Bonne chance.
Mettre les informations directement dans le controller
Cette technique est un peu plus évolué que la précédente car elle permet d'être plus DRY. En effet, si on a du code entre sa partie "dynamique" et sa vue, on est pas obligé de l'intégrer dans chaque vue. Ce qui permet d'avoir un template plus important et des vues plus légères. Mais l'inconvénient de cette technique et qu'il faut gérer l'affichage et des techniques visuel directement dans le controller. Par exemple le nom des liens, etc.. Ce n'est pas du tout dans la logique MVC, car une partie de la vue est généré et controllé par le controlleur. Le controlleur ne doit que définir quel vue utiliser et donner les variables issues d'une ressources externes.
Utiliser content_for directement dans la vue en utilisant le yield dans le template
Pour que ça soit la vue qui gère le contenu dans le template sans que le controller s'en mêle, la meilleur technique est d'utiliser content_for. Cette méthode permet de mettre en interne un bloc de code HTML. Ce bloc de code HTML n'est lu que par l'utilisation d'un yield :le_nom_du_bloc. On peux ainsi définir le bloc dans la vue et donner sa position directement dans le layout. Si ensuite vous voulez réutiliser le même bloc de code, un render :partial permettra de factoriser encore le code. Voici un exemple d'utilisation de cette méthode avec un template et une vue.
Template :
<html> <head> <title>;Ma page</title> </head> <div id="menu"> <ul> <%= yield :menu %> </ul> </div> <p>un peu de texte au milieu</p> <div id="content"> <%= yield %> </div> </html>
Vue :
<% content_for :menu do %> <li><% link_to 'Voir', page_url %></li> <% end %> <p>Ma vue compléte</p>
Vous trouvez pas ça génial ?
Sinon pour les anciens qui connaissaient la technique avant Rails 2.0 et qui utilisait @content_for_mon_block cette technique est déprécié. Il faut utiliser plutôt le yield depuis la version 2.0.x
[...]Moins de log pour ActionMailer et un compte Gmail
Si comme moi vous avez cherché un système pour envoyer un email par ActionMailer avec votre compte Gmail, vous êtes forcément tombé sur le post de Stephen Chu sur l'utilisation de votre compte Gmail avec ActionMailer.. J'ai ainsi mis sa classe dans mon WhoToWho avec une option qui permet de l'utiliser le cas échéant.
Mais voilà, par défaut il y a pas mal de logs qui sorte sur la sortie d'erreur STDERR. J'ai donc cherché comment la limiter voir la supprimer. J'ai ainsi trouvé les 2 lignes qui affichent ces logs. Il s'agit de la ligne suivante qui est répété deux fois. :
@socket.debug_output = STDERR #@debug_outputAprès avoir commenté ces lignes, je n'ai plus eu de logs. J'ai bien sûr pour WhoToWho permis de les afficher avec l'option -v.
Avec un peu de chance je devrais sortir une nouvelle version de WhoToWho très bientôt.
En lisant dans les commentaires du post de Stephen, j'ai ainsi lu que quelqu'un avait tout simplement utilisé le gem tlsmail et avait simplement ajouté la ligne suivante :
require 'tlsmail'
Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)
ActionMailer::Base.server_settings = {
:address => 'smtp.gmail.com',
:port => 587,
:domain => 'yourdomain.com',
:authentication => :plain,
:user_name => 'username',
:password => 'password'
}
C'est à tester :)
[...]Deployer un blog Typo grâce à Capistrano2
Voulant utiliser capistrano2 et mettre en place un blog Typo, j'ai décidé de déployer mon blog Typo grâce à Capistrano2. Je vais indiqué ici toutes les étapes que j'ai effectuées. Ce post aura ainsi un double intérêt.
- Expliquer comment deployer une application Typo avec Capistrano2
- Expliquer par l'exemple d'une utilisation de Capistrano2
Pour commencer Capistrano2 est vraiment très dépendant d'un système de versionning. Dans mon cas j'ai utilisé le dépôt subversion de Typo et comme je voulais utiliser leur version 4.1, j'ai récupérer l'url suivante qui est le tag de la version 4.1:
http://svn.typosphere.org/typo/tags/release_4_1/
Préparation de l'application à déployer
Préparation en local
Il faut commencer d'abord par faire un checkout complet de la version que l'on désire déployer. Ca permet surtout d'avoir une sorte de miroir de la version qui sera sur le serveur et ainsi faire des modifications sur cette version pour testé et ensuite les déployer sur le serveur.
On va maintenant commencer à créer un projet capistrano2. Pour cela, il suffit d'aller à la racine du répertoire de checkout et de lancer la commande :
capify
Grâce à cette commande le fichier config/deploy.rb est crée. C'est lui qui nous permettra de définir la configuration de notre application sur le serveur distant. Le fichier Capfile est lui aussi crée à la racine et il permet d'ajouter des tâches. Il suffit de le considérer comme une sorte de fichier de RakeFile.
Voici ce que j'ai mis dans mon fichier deploy.rb. Bien sur, il n'y avait pas ces informations à la base
set :application, "typoblog-dev"
set :repository, "http://svn.typosphere.org/typo/tags/release_4_1/"
# If you aren't deploying to /u/apps/#{application} on the target
# servers (which is the default), you can specify the actual location
# via the :deploy_to variable:
set :deploy_to, "/var/rails/#{application}"
# If you aren't using Subversion to manage your source code, specify
# your SCM below:
#set :scm, :subversion
role :app, "shingara.fr"
role :web, "shingara.fr"
role :db, "shingara.fr", :primary => true
Voici une explication de chaque champs
- set :application => Défini le nom de l'application qu'on va être déployé. C'est surtout utilisé pour le nom du répertoire de déploiement.
- set :repository => le chemin du dépôt Subversion qui sera récupéré lors du déploiement.
- set :deploy_to => Défini le répertoire sur le serveur distant où seront placés les sources de l'application
- set :scm => Le type de système de versionning qui permettra de récupérer les sources. Par défaut il s'agit de subversion.
- role :xxx => permet de définir les serveur où seront chaque rôle. serveur web, mysql et fichier. Dans mon cas il s'agit du même serveur.
Il ne reste plus qu'à voir pour le fichier Capfile, mais je le ferais dans un second temps.
Préparation sur le serveur
Il faut penser à préparer la base de donnée qui recevra les informations de notre blog. Il faut donc que la base et les accès soient prêts. C'est la seule manipulation réelle à effectuer sur le serveur.
Déploiement
On pourrait faire simple pour déployer notre application et faire ainsi :
$cap deploy:setup $cap deploy:migrations
La première tâche permettant de préparer le terrain en créant les répertoires de base. La deuxième permettant que :
- les sources soient déposées sur le serveur distant
- rake db:migrate soit lancé
- le serveur est lancé en fastcgi
Mais voilà, rien ne fonctionnera, car il n'y a pas de fichier database.yml sur le serveur car il n'existe pas sur le dépôt subversion. Il va donc falloir en ajouter un sur le serveur.
Création de tâches personnalisées
Voici le fichier CapFile que j'ai ainsi créé.
load 'deploy' if respond_to?(:namespace) # cap2 differentiator
load 'config/deploy'
after 'deploy:symlink', 'deploy:upload_database_config'
after 'deploy:symlink', 'deploy:upload_mongrel_cluster'
namespace :deploy do
desc 'Upload the config database file in release path'
task :upload_database_config do
#Define a database file
database = {'production' => {
'database' => 'typo',
'adapter' => 'postgresql',
'host' => 'localhost',
'username' => 'xxxx',
'password' => 'xxxx'
}
}
#upload
put database.to_yaml, "#{current_path}/config/database.yml", :mode => 0444
end
end
Dans ce fichier j'ai ainsi créé une nouvelle tâche. Cette tâche me permettra de créer un fichier database.yml sur le serveur et ainsi en avoir un spécifique à mon serveur. J'ai aussi défini que cette tâche sera toujours lancée après la tâche deploy:symlink. Tâche qui est réalisée lors de la tâche deploy.
Pour créer la tâche d'envoi sur le serveur du fichier database.yml, j'ai utilisé la méthode "put" de Capistrano. Elle se base sur le système de connexion au serveur pour envoyer des fichiers dessus. Avec la variable #{current_path}, j'ai pu définir le chemin vers le dossier contenant les sources utilisées pour lancer l'application.
Pour définir que cette tâche se lance après une autre tâche Capistrano, il suffit tout simplement d'appeler la méthode after.
Ca y est maintenant si vous relancez toute la procédure que je vous ai indiquée précédemment avec les tâches Cap vous aurez votre application qui démarrera avec FastCGI.
Et avec Mongrel_Rails et Nginx
Personnellement, je ne passe pas par FastCGHI, j'utilise mongrel_rails et Nginx. Donc voici les modifications que j'ai réalisées pour que tout passe de la même manière.
J'ai tout d'abord ajouté des tâches Cap:
after 'deploy:symlink', 'deploy:upload_mongrel_cluster'
namespace deploy do
desc 'Upload the mongrel_cluster.yml in release path'
task :upload_mongrel_cluster do
mongrel_conf = {'environment' => 'production',
'port' => 44000,
'pid_file' => "#{shared_path}/pids/mongrel.pid",
'servers' => 4,
'log_file' => "#{shared_path}/log/mongrel.log"}
put mongrel_conf.to_yaml, "#{current_path}/config/mongrel_cluster.yml"
end
desc 'Start mongrel_rails'
task :start do
run "cd #{current_path} && mongrel_rails cluster::start"
end
desc 'Stop mongrel_rails'
task :stop do
run "cd #{current_path} && mongrel_rails cluster::stop"
end
desc 'Restart mongrel_rails'
task :restart do
run "cd #{current_path} && mongrel_rails cluster::stop && mongrel_rails cluster::start"
end
end
Une tâche qui permet d'envoyer mon fichier mongrel_cluster.yml sur le serveur. Une tâche qui démarre le serveur avec mongrel_cluster, une tâche qui arrête le serveur et une tâche qui le redémarre. La tâche d'envoi est bien sûr après la tâche de symlink. Par contre, pour les trois autres tâches, elle remplace en fait les originales qui lancaient FastCGI.
Enfin il ne reste plus que la conf de nginx
upstream mongrel_blog_dev {
server 127.0.0.1:44000;
server 127.0.0.1:44001;
server 127.0.0.1:44002;
server 127.0.0.1:44003;
}
server {
listen 80;
server_name blog.shingara.fr;
location /log_typo {
alias /var/rails/typoblog-dev/log/;
autoindex on;
}
location / {
root /var/rails/typoblog-dev/current/public;
# needed to forward user's IP address to rails
proxy_set_header X-Real-IP $remote_addr;
# needed for HTTPS
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect false;
proxy_max_temp_file_size 0;
#redirect blog to Feedburner
if ($http_user_agent !~ FeedBurner) {
rewrite ^/xml/rss20/feed.xml$ http://feeds.feedburner.com/ProgDreamShiny;
rewrite ^/xml/rss20/comments/feed.xml$ http://feeds.feedburner.com/ProgDreamShinyComments;
}
# If the file exists as a static file serve it directly without
# running all the other rewite tests on it
if (-f $request_filename) {
break;
}
if (!-f $request_filename){
proxy_pass http://mongrel_blog_dev;
}
}
}
[...]
Un nouveau Logger dans Rails Edge
Depuis 2 jours le logger de RubyOnRails dans la version Edge a changé à partir de la révision r7626. En effet avant il y avait une classe logger qui a été remplacé par un BufferLogger.
Ce nouveau Logger est inspiré des travaux de Ezra Zygmuntowicz, qui a réalisé le framework web merb. Ce nouveau logger devrait améliorer les performances de log.
Je trouve que c'est une très bonne chose que la CoreTeam de Rails regarde aussi un peu à coté vers les nombreux framework Web en Ruby pour en prendre le meilleur.
[...]QT4 pour Ruby sous Windows
Adepte du Ruby, j'essaye de l'utiliser pour tout ce que je développe. A l'heure actuel, je développe principalement des applications web, donc je suis fortement tourné vers RubyOnRails. Mais voilà, j'ai aussi parfois des envies de Desktop. Je n'en ai jamais trop fait à part avec Swing en Java. Je me suis donc dit que ca pourrait être sympa d'utiliser QT4 en Ruby.
il existe un binding de QT4 pour Ruby. Mais j'ai hélas la possibilité de ne développé que sous Windows et sur le support Officiel, il n'y a aucune version pour Windows.
Heureusement jzkey a réaliser un binaire complet comprennant QT4 et QTRuby4. Je viens de le testé et il marche pas trop mal sur le tutorial et d'autres samples. Certain n'ont hélas pas marché, mais je n'en connais pas la raison. Je vais décrire ici la procédure pour installer QTRuby4 sous windows.
- Télécharger le zip complet comprenant QT4 et le binding Ruby sur le site de jzkey
- Dezipper le tout dans votre arborescence. Ensuite il faut faire plusieurs copier coller. (C'est en tout cas la technique que j'ai employé)
- Copier tous les fichiers (*.exe et *.dll) qui se trouve dans le dossier /bin/ et les mettres dans le dossiers /bin/ de votre dossier Ruby
- Copier le dossier /lib/ruby/site_ruby/1.8/Qt/ dans /lib/ruby/site_ruby/1.8/ de votre répertoire Ruby
- Copier les fichier QT4.rb, QT3.rb et QT.rb dans le dossier /lib/ruby/site_ruby/1.8/ de votre répertoire Ruby
- Copier le fichier qtruby4.so qui se trouve dans /lib/ruby/site_ruby/1.8/i386-msvcrt/ dans le dossier /lib/ruby/site_ruby/1.8/i386-msvcrt/ de votre répertoire Ruby
Voilà, normalement vous pouvez lancer vos applications Ruby avec le require QT4. Pour test, lancer le tutorial /samples/qt/tutorial/t14/t14.rb. Si vous arrivez à jouer au petit jeu de tir, alors l'installation à réussi et vous pouvez maintenant coder directement vos applications QT4 sous Windows.
Bien-sûr, je vous conseille toujours de développez sous Linux
Edit du 07 Août 2009 : Quelqu'un m'ayant fait remarqué que le lien sur jzkey n'existe plus, j'ai constaté que sur rubyforge, un binding windows pour qt4 est désormais disponible (http://rubyforge.org/frs/?group_id=181&release_id=32620) et même un gem. N'utilisant plus windows, je n'ai pas pu tester.
[...]