Menu
CoddyTech

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 tam 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

Hata sınıflarını ayrı tutmak, çağıranın her soruna farklı tepki vermesini sağlar; her sınıf için bir rescue kullanılır. Hata sınıflarını, onları yükselten sınıflardan önce 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ına yol açar; okumaya ise devam edilebilir. frozen? bir nesnenin dondurulmuş olup olmadığı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

Dahili bir dizi döndüren okuyucu gerçek diziyi dışarı verir, bu nedenle dışarıdaki kod onu değiştirebilir. Nesnenin kendi verileri üzerindeki denetimini korumak için @items.dup.freeze ya da @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'ı, 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ı verir. Miktar bakiyeden büyük olduğunda withdraw, balance is only 20 mesajıyla InsufficientFunds hatası verir. Hata oluştuğunda hiçbir şey değişmez.

Verilen kod, dep n veya wd n komutlarını okur ve her komuttan sonra balance 70, InvalidAmount için invalid: amount must be positive ve InsufficientFunds için refused: balance is only 20 yazdırır.

Kodunuz invalid_amount.rb, insufficient_funds.rb ve account.rb dosyalarına yazılmalıdır. main.rb, verilen girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

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

# Sağlanan giriş/çıkış 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