Menu
Coddy logo textTech

Durumu Korumak

Coddy'nin Ruby Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 20 / 57.

Bir nesne, durumunu bozacak istekleri reddetmelidir. raise, herhangi bir şey değişmeden önce yöntemi durdurur. Kendi hata sınıfınız sorunu kesin olarak adlandırır; < StandardError, sınıfı bir hata türü yapar (kalıtım, bölüm 5):

class InsufficientFunds < StandardError
end

class Account
  attr_reader :balance

  def initialize(balance)
    @balance = balance
  end

  def withdraw(amount)
    raise InsufficientFunds, "only #{balance} available" if amount > balance

    @balance -= amount
  end
end

account = Account.new(50)
begin
  account.withdraw(80)
rescue InsufficientFunds => e
  puts "#{e.class}: #{e.message}"
end
puts account.balance

Çıktı:

InsufficientFunds: only 50 available
50

Ayrı hata sınıfları, çağıranın her soruna farklı şekilde tepki vermesini sağlar; her sınıf için bir rescue kullanılır. Hata oluşturan sınıflardan önce hata sınıflarını tanımlayın:

class InvalidAmount < StandardError
end

class LimitReached < StandardError
end

class Card
  def charge(amount)
    raise InvalidAmount, "amount must be positive" unless amount.positive?
    raise LimitReached, "limit is 100" if amount > 100

    "charged #{amount}"
  end
end

[40, -5, 500].each do |amount|
  puts Card.new.charge(amount)
rescue InvalidAmount => e
  puts "fix the input: #{e.message}"
rescue LimitReached => e
  puts "try later: #{e.message}"
end

Çıktı:

charged 40
fix the input: amount must be positive
try later: limit is 100

freeze bir nesneyi salt okunur hâle getirir: bundan sonra örnek değişkenlerinde yapılan herhangi bir değişiklik FrozenError hatası oluştururken okuma işlemi çalışmaya devam eder. frozen? bir nesnenin dondurulup dondurulmadığını belirtir:

class Point
  attr_accessor :x

  def initialize(x)
    @x = x
  end
end

pt = Point.new(1).freeze
puts pt.frozen?
begin
  pt.x = 2
rescue FrozenError => e
  puts e.class
end
puts pt.x

Çıktı:

true
FrozenError
1

Bir iç dizi döndüren okuyucu, gerçek diziyi dışarıya verir; bu nedenle dış kod onu değiştirebilir. Nesnenin kendi verileri üzerindeki kontrolünü korumak için @items.dup.freeze veya @items.dup ile dondurulmuş bir kopya döndürün:

class Playlist
  def initialize
    @songs = []
  end

  def add(song)
    @songs << song
  end

  def songs
    @songs.dup.freeze
  end
end

list = Playlist.new
list.add("Intro")
begin
  list.songs << "Hack"
rescue FrozenError
  puts "songs are read-only"
end
p list.songs

Çıktı:

songs are read-only
["Intro"]
challenge icon

Görev

Kolay

Hata sınıfları InvalidAmount ve InsufficientFunds'ı, her ikisi de StandardError alt sınıfı olacak şekilde tanımlayın ve Account sınıfını tamamlayın. deposit(amount) ve withdraw(amount), 1'in altındaki miktarlar için amount must be positive mesajıyla InvalidAmount hatası oluşturur. Miktar bakiyeden büyük olduğunda withdraw, balance is only 20 mesajıyla InsufficientFunds hatası oluşturur. Bir hata oluşturulduğunda hiçbir şey değişmez.

Sağlanan kod dep n veya wd n komutlarını okur ve her birinin ardından balance 70 yazdırır; InvalidAmount için invalid: amount must be positive, InsufficientFunds için ise refused: balance is only 20 yazdırır.

Kodunuz invalid_amount.rb, insufficient_funds.rb ve account.rb dosyalarına yerleştirilmelidir. main.rb, sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

require_relative 'invalid_amount'
require_relative 'insufficient_funds'
require_relative 'account'

# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
input = []
while (line = gets)
  input << line.chomp
end
account = Account.new
input.each do |line|
  action, amount = line.split
  begin
    action == "dep" ? account.deposit(amount.to_i) : account.withdraw(amount.to_i)
    puts "balance #{account.balance}"
  rescue InvalidAmount => e
    puts "invalid: #{e.message}"
  rescue InsufficientFunds => e
    puts "refused: #{e.message}"
  end
end
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online Ruby derleyicisi