Menu
Coddy logo textTech

Modules et include

Fait partie de la section Programmation orientée objet du Journey Ruby de Coddy. Leçon 27 sur 57.

Un module est un groupe nommé de méthodes. Il ne peut pas créer d’objets, mais une classe peut l’include, et chaque instance possède alors les méthodes du module comme si la classe les avait définies. C’est ce qu’on appelle un mixin :

module Greetable
  def greet
    "Hello, I am #{name}"
  end
end

class Person
  include Greetable
  attr_reader :name

  def initialize(name)
    @name = name
  end
end

puts Person.new("Ada").greet

Sortie :

Hello, I am Ada

Les méthodes d’un module peuvent appeler les méthodes fournies par la classe, comme name ci-dessus. Ainsi, un même module peut servir à des classes très différentes, tant que chacune fournit ce que le module utilise :

module Greetable
  def greet
    "Hello, I am #{name}"
  end
end

class Robot
  include Greetable

  def name
    "R2"
  end
end

class City
  include Greetable

  def name
    "Paris"
  end
end

puts Robot.new.greet
puts City.new.greet

Sortie :

Hello, I am R2
Hello, I am Paris

Une classe n’a qu’une seule superclasse, mais peut inclure un nombre quelconque de modules. include? demande si une classe inclut un module, et le module apparaît dans ancestors, juste après la classe, qui est l’endroit où Ruby recherche ses méthodes :

module Swimmer
  def swim
    "swimming"
  end
end

module Flyer
  def fly
    "flying"
  end
end

class Duck
  include Swimmer
  include Flyer
end

d = Duck.new
puts "#{d.swim}, #{d.fly}"
puts Duck.include?(Flyer)
p Duck.ancestors.take(3)

Sortie :

swimming, flying
true
[Duck, Flyer, Swimmer]

Les modules regroupent également des classes et des constantes associées sous un même nom, un espace de noms, afin d’éviter les conflits de noms. Shop::Item et Game::Item sont des classes différentes :

module Shop
  TAX = 0.2

  class Item
    def label
      "shop item, tax #{TAX}"
    end
  end
end

puts Shop::Item.new.label
puts Shop::TAX

Résultat :

shop item, tax 0.2
0.2
challenge icon

Défi

Facile

Complétez les modules et les classes. Greetable#greet renvoie Hello, I am Ada, en utilisant le name de l'objet. Walkable#walk(steps) ajoute les étapes à un compteur conservé dans @steps (qui vaut nil la première fois) et renvoie Ada walked 30 steps, le total cumulé. Person inclut les deux modules ; Robot inclut uniquement Greetable et son nom est R- suivi d'un numéro de série.

Le code fourni crée une personne et un robot à partir de la première ligne (Ada 7), puis exécute les commandes greet p, greet r ou walk 10 (pour la personne) et affiche chaque résultat, puis finalement robot walks: false.

Votre code doit être placé dans greetable.rb, walkable.rb, person.rb et robot.rb. main.rb contient le code d'entrée/sortie fourni et ne peut pas être modifié.

Essayez vous-même

require_relative 'greetable'
require_relative 'walkable'
require_relative 'person'
require_relative 'robot'

# Code d'entrée/sortie fourni : le garder tel quel
input = []
while (line = gets)
  input << line.chomp
end
name, serial = input[0].split
person = Person.new(name)
robot = Robot.new(serial)
input.drop(1).each do |line|
  command, arg = line.split
  if command == "walk"
    puts person.walk(arg.to_i)
  else
    target = arg == "p" ? person : robot
    puts target.greet
  end
end
puts "robot walks: #{Robot.include?(Walkable)}"
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation orientée objet

Entraînez-vous par vous-même : Compilateur Ruby en ligne