Programmation Ruby/Premiers essais

Pour faire les premiers essais avec Ruby, nous allons utiliser l'outil irb, un interpréteur Ruby très pratique pour tester et déboguer.

Pour le lancer sous Windows un raccourci a été défini au chapitre précédent, et avec Unix à partir d'un terminal via la commande irb :

# irb 

Pour ne pas déroger à la règle, nous allons pour premier exemple dire bonjour :

 
irb(main):001:0> puts "Hello World"

Ceci renverra :

Hello World 
=> nil 

soit l'effet produit par notre fonction (l'affichage de la chaîne "Hello World"), et la valeur de retour de celle-ci, dans notre cas nil.

Pour un langage objet, cet exemple n'est pas très adapté. Il faut néanmoins savoir que tout code écrit en dehors d'une classe ou d'un module fait partie de la classe Object.

On aurait également pu écrire cet exemple de cette manière :

 
irb(main):013:0> STDOUT << "Hello" << " " + "World"

L'approche objet est ici plus évidente : la méthode "<<" de l'objet STDOUT est appelée avec « "Hello" << " " + "World" » comme paramètre. De même on appelle la méthode "<<" de l'objet « "Hello" » (qui est une instance de l'objet String).

On découvre ici le modèle tout objet de Ruby. En effet, celui-ci ne comporte pas de type primaire, ainsi, une chaîne de caractères ou un nombre sont des objets, comme on peut le voir avec la méthode Object.class :

irb(main):016:0> 3.class 
=> Fixnum 
irb(main):017:0> "Hello".class 
=> String 
irb(main):018:0> /^Hello\sWorld$/.class 
=> Regexp 

Bien sûr, chacun de ces objets possède ses propres méthodes, que l'on peut lister ainsi :

irb(main):019:0> Fixnum.methods 
=> ["method", "send", "name", "class_eval", "object_id", "singleton_methods", "__send__",
"private_method_defined?", "equal?", "taint", "frozen?", "instance_variable_get", "constants",
"kind_of?",  "to_a", "instance_eval", "ancestors", "const_missing", "type", "instance_methods",
"protected_methods", "extend", "protected_method_defined?", "eql?", "public_class_method", "const_get",
"display", "instance_variable_set", "hash", "is_a?", "to_s", "class_variables", "class", "tainted?",
"private_methods", "public_instance_methods", "autoload", "untaint", "included_modules",
"private_class_method", "const_set", "id", "<", "inspect", "<=>", "instance_method", "==",
"induced_from", "method_defined?", ">", "===", "clone", "public_methods", "protected_instance_methods",
">=", "respond_to?", "freeze", "<=", "module_eval", "allocate", "__id__", "=~", "methods",
"public_method_defined?", "superclass", "nil?", "dup", "autoload?", "private_instance_methods", 
"instance_variables", "include?", "const_defined?", "instance_of?"] 

ou encore dans un contexte précis :

irb(main):020:0> 3.methods 
=> ["%", "between?", "method", "send", "<<", "prec", "modulo", "&", "object_id", ">>", "zero?", "size",
"singleton_methods", "__send__", "equal?", "taint", "id2name", "*", "next", "frozen?",
"instance_variable_get", "+", "kind_of?", "step", "to_a", "instance_eval", "-", "remainder", "prec_i",
"nonzero?", "/", "type", "protected_methods", "extend", "floor", "to_sym", "|", "eql?", "display", "quo",
"instance_variable_set", "~", "hash", "is_a?", "downto", "to_s", "prec_f", "abs",
"singleton_method_added", "class", "tainted?", "coerce", "private_methods", "^", "ceil", "untaint", "+@",
"upto", "-@", "div", "id", "**", "times", "to_i", "<", "inspect", "<=>", "==", ">", "===", "succ",
"clone", "public_methods", "round", ">=", "respond_to?", "<=", "freeze", "divmod", "chr", "to_f",
"__id__", "integer?", "=~", "methods", "nil?", "dup", "to_int", "instance_variables", "[]",
"instance_of?", "truncate"] 

On constate certaines particularités syntaxiques ; nous les détaillerons plus tard même si elles sont assez claires ; par exemple une méthode dont le nom se termine par "?" indique que celle-ci renvoie un booléen.

Pour plus d'informations sur un objet ou une méthode, vous pouvez, à partir d'un terminal, exécuter la commande « ri » :

# ri times 

Si une méthode est incluse dans plusieurs objets, « ri » vous proposera une liste de choix possibles.

Toute méthode peut être redéfinie :

irb(main):029:0> 2+3 
=> 5 

irb(main):030:0> class Fixnum 
irb(main):031:1> def +(value) 
irb(main):032:2> return self-value 
irb(main):033:2> end 
irb(main):034:1> end 

irb(main):035:0> 2+3 
=> -1 

Toutes les méthodes peuvent ainsi être redéfinies, cependant, cette fonctionnalité est à utiliser avec précaution.

Pour finir cette présentation nous allons voir la notion de bloc en Ruby, et voir comment ceux-ci peuvent être utilisés. Par exemple :

irb(main):024:0> 5.times do |i| 
irb(main):025:1* puts "#{i}\n" 
irb(main):026:1> end 
0 
1 
2 
3 
4 

Ici nous voyons que le bloc délimité par do et end (Il est à noter que l'on peut également délimiter les blocs par des accolades ouvrantes et fermantes { } ) est envoyé en paramètre à la méthode times de l'objet Fixnum. Les valeurs entre pipes (ici la variable i) indiquent les paramètres que la méthode passe au bloc. Ici, la méthode times va donc appeler 5 fois le bloc en y passant en paramètre un entier valant au départ 0 et qui sera incrémenté de 1 à chaque appel du bloc.

Tous ces concepts seront vus en détail dans les chapitres suivants.