Menu
Coddy logo textTech

self dans les méthodes

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

Dans une méthode, name = value crée toujours une variable locale, même lorsque la classe possède un setter name=. Pour appeler le setter, écrivez le récepteur : self.name = value :

class Player
  attr_accessor :level

  def initialize
    @level = 1
  end

  def broken_level_up
    level = level + 1
  rescue NoMethodError
    puts "level is a new local variable here, still nil"
  end

  def level_up
    self.level = level + 1
  end
end

p1 = Player.new
p1.broken_level_up
p1.level_up
puts p1.level

Sortie :

level is a new local variable here, still nil
2

Les lecteurs n’ont pas besoin de self. : level et self.level appellent la même méthode. Le style habituel consiste à écrire self. uniquement là où Ruby en a besoin, devant un accesseur en écriture :

class Rect
  attr_accessor :w, :h

  def initialize(w, h)
    @w = w
    @h = h
  end

  def area
    w * h
  end

  def double!
    self.w = w * 2
    self.h = self.h * 2
    self
  end
end

puts Rect.new(2, 3).double!.area

Sortie :

24

Appeler le setter depuis initialize avec self. fait passer aux nouveaux objets la même vérification que les modifications ultérieures, de sorte que la règle se trouve à un seul endroit :

class Product
  attr_reader :price

  def initialize(price)
    self.price = price
  end

  def price=(value)
    raise ArgumentError, "price must be positive" if value <= 0

    @price = value
  end
end

puts Product.new(5).price
begin
  Product.new(0)
rescue ArgumentError => e
  puts e.message
end

Résultat :

5
price must be positive

Ce que représente self dépend de l’endroit où le code s’exécute. À l’intérieur d’une méthode d’instance, il s’agit de l’instance ; dans le corps de la classe, en dehors de toute méthode, il s’agit de la classe elle-même :

class Robot
  puts "in the class body, self is #{self}"

  def whoami
    "in a method, self is a #{self.class}"
  end
end

puts Robot.new.whoami

Sortie :

in the class body, self is Robot
in a method, self is a Robot
challenge icon

Défi

Facile

La classe Account possède un setter personnalisé balance= qui lève ArgumentError avec balance cannot be negative pour une valeur inférieure à 0. Complétez initialize(owner, balance), deposit(amount) et withdraw(amount) afin que chaque modification du solde passe par ce setter avec self., y compris le solde initial.

Le code fourni lit le propriétaire et le solde initial, puis les commandes +n (dépôt) ou -n (retrait). Il affiche Ada: 120 après chaque commande, ou le message d’erreur et le solde inchangé. Un solde initial invalide affiche uniquement le message d’erreur.

Votre code doit être placé dans account.rb. main.rb contient le code fourni pour les entrées et les sorties et ne peut pas être modifié.

Essayez vous-même

require_relative 'account'

# Code d'entrée/sortie fourni : le garder tel quel
input = []
while (line = gets)
  input << line.chomp
end
begin
  account = Account.new(input[0], input[1].to_i)
  input.drop(2).each do |cmd|
    begin
      amount = cmd[1..].to_i
      cmd.start_with?("+") ? account.deposit(amount) : account.withdraw(amount)
    rescue ArgumentError => e
      puts e.message
    end
    puts "#{account.owner}: #{account.balance}"
  end
rescue ArgumentError => e
  puts e.message
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