Menu
Coddy logo textTech

Méthodes privées

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

L'encapsulation signifie qu'un objet dissimule son fonctionnement et propose un petit ensemble de méthodes publiques. Les méthodes sont publiques par défaut. Toute méthode définie après le mot private dans le corps d'une classe est privée : les propres méthodes de l'objet peuvent l'appeler, mais le code externe ne le peut pas :

class Order
  def initialize(price, quantity)
    @price = price
    @quantity = quantity
  end

  def total
    subtotal + shipping
  end

  private

  def subtotal
    @price * @quantity
  end

  def shipping
    subtotal >= 50 ? 0 : 5
  end
end

order = Order.new(10, 3)
puts order.total
begin
  order.subtotal
rescue NoMethodError => e
  puts e.message
end

Sortie :

35
private method `subtotal' called for an instance of Order

À l’intérieur de la classe, une méthode privée est appelée sans récepteur ou avec self.. L’appeler sur un autre objet, même s’il appartient à la même classe, est refusé :

class Coin
  def initialize(cents)
    @cents = cents
  end

  def describe
    "#{self.label} / #{label}"
  end

  def same_as?(other)
    other.label == label
  end

  private

  def label
    "#{@cents}c"
  end
end

a = Coin.new(5)
puts a.describe
begin
  a.same_as?(Coin.new(5))
rescue NoMethodError => e
  puts e.message
end

Sortie :

5c / 5c
private method `label' called for an instance of Coin

private peut également recevoir un nom de méthode, et def renvoie le nom de la méthode ; ainsi, private def helper rend une seule méthode privée à l’endroit même où elle est définie. Les méthodes situées au-dessus et autour restent publiques :

class Greeter
  def greet(name)
    "#{salutation}, #{name}!"
  end

  private def salutation
    "Hello"
  end

  def wave
    "*waves*"
  end
end

g = Greeter.new
puts g.greet("Ada")
puts g.wave
p Greeter.private_instance_methods(false)

Sortie :

Hello, Ada!
*waves*
[:salutation]

Gardez les méthodes auxiliaires privées. Les méthodes publiques sont la promesse qu’une classe fait au reste du programme  les méthodes privées peuvent être renommées ou supprimées plus tard sans interrompre aucun appelant :

class Invoice
  def total              # public : les appelants s'y fient
    net + tax
  end

  private                # libre de changer plus tard

  def net
    ...
  end

  def tax
    ...
  end
end
challenge icon

Défi

Facile

Complétez la classe Order. Son seul méthode publique en dehors de initialize est receipt, qui renvoie 3 x 12.50 = 37.50, tax 7.50, total 45.00. Les méthodes privées subtotal (prix multiplié par la quantité), tax (20 % du sous-total) et total calculent les nombres.

Le code fourni lit les commandes sous forme de lignes quantity price et affiche chaque reçu. Ensuite, il essaie d'appeler tax depuis l'extérieur et affiche tax is private lorsque Ruby refuse.

Votre code doit se trouver dans order.rb. main.rb contient le code d'entrée/sortie fourni et ne peut pas être modifié.

Essayez vous-même

require_relative 'order'

# Code d'entrée/sortie fourni : le garder tel quel
input = []
while (line = gets)
  input << line.chomp
end
orders = input.map do |line|
  quantity, price = line.split
  Order.new(quantity.to_i, price.to_f)
end
orders.each { |o| puts o.receipt }
begin
  orders[0].tax
  puts "tax is public"
rescue NoMethodError
  puts "tax is private"
end
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