Expansion Pak No. 1.

La Veste du Tigre (avec une Introduction Basique à Irb)

Tiger has vest.  Tiger likes girl robot.  Earth crashing into sun...

Installons la toute dernière version de Ruby sur votre ordinateur afin de pouvoir suivre tous les exemples dans le Guide (Poignant) et faire des choses maintenant! (Oui, des choses!)

  • Si vous utilisez Microsoft Windows, commencez par télécharger l’Installateur de Ruby pour Windows. L’exécutaion de cet installateur “1-click” installera Ruby pour vous, ainsi qu’un ensemble de logiciels utiles, tels qu’un petit éditeur et quelques bibliothèques additionnelles.
  • Si vous êtes sur Mac OS X, alors Ruby pourrait bien déjà être installé. Les version 10.2 et 10.3 d’OS X possèdent déjà Ruby. Mais je vous encourage quand même à actualiser votre version de Ruby afin que tous les exemples de ce livre marchent chez vous. Télécharger une image disque stable. Vous aurez besoin à la fois d’OS X 10.3 (Panther) et des outils XCode pour utiliser cette image.
  • Sur FreeBDS, Ruby fait parti du système de ports. En fait, si vous avez utilisé l’outil essentiel qu’est portupgrade, alors Ruby est déjà installé. Akinoru Musha, l’un des immensément talentueux développeurs de Ruby a écrit portupgrade, ce qui veut dire que vous pouvez utiliser votre connaissance de Ruby pour jouer avec votre pkgtools.conf.
       cd /usr/ports/lang/ruby18
       sudo make install
      
  • Sur les distributions de Linux RedHat ou Mandrake, vous pouvez trouver les RPMs Ruby. Je pense que Ruby est aussi disponible via Red Carpet de Ximian.
  • Sur Debian, utilisez apt-get install ruby.
  • Sur Gentoo, emerge ruby.
  • Pour les autres plateformes Linux et UNIX, et même OS X (si les images disque ne marchent pas pour vous): Téléchargez le dernier code source. Par exemple Ruby 1.8.3. Pour décompresser et compiler:
 tar xzvf ruby-1.8.3.tar.gz
 cd ruby-1.8.3
 ./configure
 make
 make install

(Encore une fois, les commandes précédentes sont nécessaires pour installer Ruby à partir du code source. Vous pouvez avoir besoin d’utiliser su ou sudo pour acquérir les droits nécessaires à l’execution de make install.)

Pour vérifier si Ruby est installé, ouvrez un shell et tapez: ruby -v. Si Ruby est installé proprement, vous verez quelques infos sur la version.

 ruby 1.8.3 (2005-11-25) [i386-mswin32]
  • Pour ouvrir un shell sous Microsoft Windows, allez dans le menu Demarrez et sélectionner Exécuter.... Tapez alors: cmd. Appuez sur OK. Une fenêtre avec un shell apparaitra.
  • Pour ouvrir un shell sous Mac OS X, allez dans Applications → Utilities. Lancer le programme Terminal.

OK, gardez ce shell ouvert car nous en aurons besoin si la Terre est sauvée de son plongeon vers le soleil.

Tiger saves Earth with Ice Gun.  Girl robot zooms around tuxed shop...

Ruby est livré avec un outil très, très, très utile appelé Irb. Interactive Ruby (NDT: Ruby Interactif). Dans votre shell, tapez: irb.

 irb(main):001:0>

Vous devriez voir le prompt ci-dessus. Ce prompt d’Irb vous permet de rentrer du code Ruby, et après avoir presser sur Entrée, le code s’exécutera:

Donc, au prompt Irb, tapez: 3000 + 500.

 irb(main):001:0> 3000 + 500
 => 3500
 irb(main):002:0>

L’exemple 3000 + 500 est du code valable. Le résultat n’est pas assigné à une variable. Ce qui ne pose pas de problème avec Irb, car il affiche la réponse rendue par le code que vous exécutez.

Irb fait une bonne calculatrice.

 irb(main):002:0> ( ( 220.00 + 34.15 ) * 1.08 ) / 12
 => 22.8735
 irb(main):003:0> "1011010".to_i( 2 )
 => 90
 irb(main):004:0> Time.now - Time.local( 2003, "Jul", 31, 8, 10, 0 )
 => 31119052.510118

Le premier exemple montre un peu de math et peut se lire comme: 220.00 plus 34.15 fois 1.08 divisé par 12. Le deuxième exemple prend une chaîne binaire et la convertit en nombre décimal. Le troisème exemple calcule le nombre de secondes entre maintenant et Le 31 Juillet 2003 à 8 heures 10. Les réponses de chacun de ces exemples sont affichées par Irb, avec une petite flêche en ASCII les pointant.

Lire le Prompt.

Je sais que l’invite peut sembler déroutante. Donc, n’attendons pas plus pour la disséquer. C’est très simple. L’invite est faitre de trois parties, séparées par deux points.

La première partie, irb(main), montre le nom du programme que nous exécutons. La seconde partie montre un numéro de ligne, le nombre de lignes de Ruby que nous avons tapé. La troisième partie est une profondeur. Chaque fois que vous ouvrez une déclaration qui doit être fermée, la profondeur augmentera de un. Et dès qu’Irb devinera que votre code n’est pas terminé, la fin de l’invite deviendra une étoile.

 irb(main):001:0> bell = :pressed
 => :pressed
 irb(main):002:0> ice_gun =
 irb(main):003:0*   if bell == :pressed
 irb(main):004:1>     :on
 irb(main):005:1>   else
 irb(main):006:1*     :off
 irb(main):007:1>   end
 => :on

Notez comme la profondeur est passée à 1 lorsque j’ai tapé un if. Et comme l’étoile indique la continuation de la ligne.

Modifier l’Invite

Remarquez que vous n’êtes pas obligé d’aimer l’apparence de l’invite. Je ne vous force à rien, et si vous voulez le modifier, je suis là, juste derrière vous.

Irb possède quelques autres invites par défaut qui pourraient peut-être plus apaiser vos sens. Essayez irb --prompt simple. Cette fois, Irb va vous servir de simple flêches, vous permettant de taper votre code sans tout le rapport d’état.

 >> %w(my best friend's arm)
 => ["my", "best", "friend's", "arm"]
 >>

Ruby vient avec quelques invites. L’invite simple vient d’être vue. L’invite xmp qui n’a pas d’invite du tout et indente la flêche de la réponse. (C’est supposé être joli à l’impression). Et aussi le l’invite null, qui élimine toute invite. Choisissez l’invite en forunissant le nom à l’option --prompt. (Par exemple irb --prompt null.)

Vous pouvez tout aussi bien faire votre propre invite. Irb est totalement configurable depuis son prpore intérieur. L’objet conf contient toute les options de configuration d’Irb. Certaines de ces options servent à controller l’invite.

 >> conf.methods.grep /prompt/
 => ["prompting?", "prompt_s", "prompt_s=", "prompt_c", "prompt_c=", 
     "prompt_i", "prompt_mode", "prompt_i=", "prompt_mode="]

Créons notre propre invite qui affichera les numéros de ligne avec juste un peu de décoration.

 >> conf.prompt_i = "%3n :> "           # l'invite normal
 >> conf.prompt_s = "%3n .%l "          # l'invite de continuation de chaine.
 >> conf.prompt_c = "%3n .^ "           # l'invite de continuation de code.
 >> conf.return_format = "    => %s\n"  # la flêche de la réponse.

Voici les quatre parties d’une invite Irb. L’invite de continuation de chaîne est affichée lorsque une chaîne est toujours ouverte et que vous tapez Entrée. Le %3n signifie qu’Irb doit réserver trois caractères pour le numéro de ligne. Le %l garde un peu de place pour afficher le type de chaîne qui est continuée. (Si vous continuez une chaîne avec des guillemets doubles, il montre des guillemets doubles. Si vous continuez une expression régulière, il montre un /.)

Le reste ne sont que de petits symboles pour décorer l’invite. Donc, dans la cas d’une continuation de ligne de code, j’affiche un chapeau chinois qui pointe vers la ligne ou le code a commencé.

Vous pouvez lire plus concernant la configuration d’Irb ainsi que sa sauvegarde dans le guide complet d’Irb, disponible dans le gartuit-pour-vos-yeux-vagabind-d-Internet Programming Ruby.

Tab Completion

One feature of Irb which is rarely mentioned is its beneficial tab completion. And it’s a bit of a taboo topic at the moment, since getting it to work on Windows is a slight horror. (No, don’t be afraid. All at once now, look to your right.)

If you’re on Linux or FreeBSD, the tab completion should work right off. And if you’re using OS X, you should be sure you’re upgrade to the latest 1.8 and when run Irb, use:

 irb --readline -r irb/completion

Basically, when you hit Tab, Irb will take a guess at what you’re trying to type. Try typing: [].col and hit Tab. Irb will finish it. [].collect and it leaves your cursor at the end so you can add further.

If there are several matches, just hitting Tab will do nothing. But hit it twice and Ruby will give you a complete list of possible matches.

This is great if you just want to see all the methods for a certain object. Type in any number, a dot, and use Tab.

  >> 42.
                42.floor                   42.next                    42.step
  42.__id__     42.freeze                  42.nil?                    42.succ
  42.__send__   42.frozen?                 42.nonzero?                42.taint
  42.abs        42.hash                    42.object_id               42.tainted?
  42.between?   42.id                      42.prec                    42.times
  42.ceil       42.id2name                 42.prec_f                  42.to_f
  42.chr        42.inspect                 42.prec_i                  42.to_i
  42.class      42.instance_eval           42.private_methods         42.to_int
  42.clone      42.instance_of?            42.protected_methods       42.to_s
  42.coerce     42.instance_variable_get   42.public_methods          42.to_sym
  42.display    42.instance_variable_set   42.quo                     42.truncate
  42.div        42.instance_variables      42.remainder               42.type
  42.divmod     42.integer?                42.respond_to?             42.untaint
  42.downto     42.is_a?                   42.round                   42.upto
  42.dup        42.kind_of?                42.send                    42.zero?
  42.eql?       42.method                  42.singleton_method_added  
  42.equal?     42.methods                 42.singleton_methods       
  42.extend     42.modulo                  42.size  

Now, trying typing Kernel:: and then Tab. All the core methods. Don’t ever forget this and use it all the time.

Except the robot flew away and the ice gun went on and on...

Okay, one last thing and then I’ll quit bugging you with all this great technology. But I have to say it loud, so take cover! I’m across the world here, folks, but the volume comes down from the sky—a bold, red crescendo of—

((ri))

(Ruby’s Own 411 or 555-1212 or Yes, Operator, Get Belgrade on the Line—I’ll Be Right Here—Just Plain Hammering The Pound Key Until Someone Picks Up…)

And Ri picks up the line. “This is Ri. Class and colon, please.”

You rush in, “This is an instance method, Operator. Enumerable#zip.”

 ri Enumerable#zip

Without delay, right up on your teletype display (so swiftly that even the cat perched atop cranes his neck around, gapes and hands it the royal cup Most Blatantly Great Thing Since Michael Dorn):

 --------------------------------------------------------- Enumerable#zip
      enum.zip(arg, ...)                   => array
      enum.zip(arg, ...) {|arr| block }    => nil
 ------------------------------------------------------------------------
      Converts any arguments to arrays, then merges elements of _enum_
      with corresponding elements from each argument. This generates a
      sequence of +enum#size+ _n_-element arrays, where _n_ is one more
      that the count of arguments. If the size of any argument is less
      than +enum#size+, +nil+ values are supplied. If a block given, it
      is invoked for each output array, otherwise an array of arrays is
      returned.

         a = [ 4, 5, 6 ]
         b = [ 7, 8, 9 ]

         (1..3).zip(a, b)      #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
         "cat\ndog".zip([1])   #=> [["cat\n", 1], ["dog", nil]]
         (1..3).zip            #=> [[1], [2], [3]]

It’s an unabridged Ruby dictionary servo—the Power of Just Asking is at your fingertips—don’t tell me you’ve never heard of this no-money-down lifetime-supply-of-proper-explanations!

To get an explanation of any class, along with a complete directory to all of its methods, all in a very soothing voice fit for calming any of you panicking cosmonauts out there fighting the pull of some zero-tolerance tractor beam, just use at your command shell: ri Class.

But for help on class methods, you cuff on: ri Class::method.

Though instance methods use a pound key rather than a dot. (Since the dot can mean class or instance methods.) I mean: ri Class#method.

The full spread of classes, a full list from the Very Top down to the Earth’s core, can be achieved with ri -c.

And beyond text, you can make HTML: ri -Tf html String#gsub > gsub.html.

Or show colory ANSI: ri -Tf ansi String#gsub. And this is last and best.

Into the Ri Switchboard

Behind Ri sings a chorus of human voices, primarily Dave Thomas, an author of Programming Ruby, and absolutely the American foster parent of Ruby. Many of these elaborate spiels from Ri are straight from the references of Programming Ruby. Don’t forget to thank Dave periodically.

Ri culls its lush information set from the very code that Ruby is built from. In each of the files of code back in the Ruby Headquarter’s file cabinet, detailed comments describe everything in sight.

In Ruby’s date class, here we have such commented methods:

 # Get the time of this date as [hours, minutes, seconds,
 # fraction_of_a_second]
 def time() self.class.day_fraction_to_time(day_fraction) end

 # Get the hour of this date.
 def hour() time[0] end

 # Get the minute of this date.
 def min() time[1] end

The comments show up in Ri. We type: ri Date#time.

 -------------------------------------------------------------- Date#time
      time()
 ------------------------------------------------------------------------
      Get the time of this date as [hours, minutes, seconds,
      fraction_of_a_second]

Ri figures out much of how a method works, although it expects coders to write a brief description in the comments just before a method or class definition. I would suggest that whenever you write a method, add a brief description in the comments before that method. In time, you can generate Ri documentation for that method.

You can also use a few special characters to enhance your description. For example, if you indent a paragraph and use an asterisk * or a dash - just before the letters of the first sentence, the paragraph will be recognized as a list item. Then, if your description needs to be converted to HTML, you’ll see the list item appear as an HTML unordered list.

 # Get the time of this date as an Array of:
 # * hours
 # * minutes
 # * seconds
 # * fraction_of_a_second
 def time() self.class.day_fraction_to_time(day_fraction) end

Other rules as well: Lists which start with digits followed by periods are recognized as numbered lists. Emphasized words are surrounded by underscores, bold words by asterisks, code words by plus signs. Examples are simply blocks of text indented a few spaces. All of these rules together are called RDoc.

Here’s a bit of RDoc from the initialize method in one of my projects called RedCloth. Notice the indented example as well as the Ruby class and method names flanked with plusses.

 #
 # Returns a new RedCloth object, based on +String+ and
 # enforcing all the included +restrictions+.
 #
 #   r = RedCloth.new( "h1. A <b>bold</b> man", [:filter_html] )
 #   r.to_html
 #     #=>"<h1>A &amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt; man</h1>" 
 #
 def initialize( string, restrictions = [] )
     @lite = false
     restrictions.each { |r| method( "#{ r }=" ).call( true ) }
     super( string )
 end

For the full set of RDoc rules see the Markup section of the README.

Pushing Out Your Own Ri

Ri doesn’t automatically read your files for you, though. You’ve got to push it along, show it the way. Change to the directory of the code you’d like to scan. Then, use the RDoc tool to make it happen.

 cd ~/cvs/your-code
 rdoc --ri-site

Now, try using ri YourClass to ensure all your descriptions are showing up properly. If you want to make HTML documentation, try this:

 cd ~/cvs/your-code
 rdoc

The ~/cvs/your-code directory should now also have a fresh doc directory containing HTML documentation for all of your classes. View index.html for the pleasant news.

Well then. Your hands are in it all now. Welcome to Ruby.

The tiger finds a new home and learns to eventually move on.

Tournez la page.