Menu
Coddy logo textTech

Moduli e include

Fa parte della sezione Programmazione orientata agli oggetti del percorso Ruby di Coddy. Lezione 27 di 57.

Un modulo è un gruppo di metodi con un nome. Non può creare oggetti, ma una classe può includerlo con include, e quindi ogni istanza ha i metodi del modulo come se fossero definiti dalla classe. Questo si chiama 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

Output:

Hello, I am Ada

I metodi di un modulo possono chiamare i metodi forniti dalla classe, come name qui sopra. Quindi un modulo può essere usato da classi molto diverse, purché ciascuna offra ciò che il modulo utilizza:

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

Output:

Hello, I am R2
Hello, I am Paris

Una classe ha una sola superclasse, ma può includere un numero qualsiasi di moduli. include? verifica se una classe include un modulo, e il modulo compare in ancestors, subito dopo la classe: è lì che Ruby cerca i suoi metodi:

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)

Output:

swimming, flying
true
[Duck, Flyer, Swimmer]

I moduli raggruppano anche classi e costanti correlate sotto un unico nome, uno spazio dei nomi, così che i nomi non entrino in conflitto. Shop::Item e Game::Item sono classi diverse:

module Shop
  TAX = 0.2

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

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

Output:

shop item, tax 0.2
0.2
challenge icon

Sfida

Facile

Completa i moduli e le classi. Greetable#greet restituisce Hello, I am Ada, usando il name dell'oggetto. Walkable#walk(steps) aggiunge i passi a un contatore mantenuto in @steps (che la prima volta parte da nil) e restituisce Ada walked 30 steps, il totale progressivo. Person include entrambi i moduli; Robot include solo Greetable e il suo nome è R- seguito da un numero di serie.

Il codice fornito crea una persona e un robot a partire dalla prima riga (Ada 7), poi esegue i comandi greet p, greet r o walk 10 (per la persona), stampa ogni risultato e infine robot walks: false.

Il tuo codice va in greetable.rb, walkable.rb, person.rb e robot.rb. main.rb contiene il codice di input/output fornito e non può essere modificato.

Provalo tu

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

# Codice di input/output fornito: lascialo così com'è
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 iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Ruby online