Menu
Coddy logo textTech

Metotlarda self

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

Bir metodun içinde, sınıfın name= adlı bir setter'ı olsa bile name = value her zaman bir yerel değişken oluşturur. Setter'ı çağırmak için alıcıyı yazın: 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

Çıktı:

level is a new local variable here, still nil
2

Okuyucuların self. kullanmasına gerek yoktur: level ve self.level aynı yöntemi çağırır. Yaygın stil, self. ifadesini yalnızca Ruby'nin ona ihtiyaç duyduğu yerde, bir setter'ın önünde kullanır:

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

Çıktı:

24

initialize içinden self. kullanarak setter'ı çağırmak, yeni nesnelerin sonraki değişikliklerle aynı denetimden geçmesini sağlar; böylece kural tek bir yerde bulunur:

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

Çıktı:

5
price must be positive

self'in ne olduğu, kodun nerede çalıştığına bağlıdır. Bir örnek yönteminin içinde örnektir; her yöntemin dışında, sınıf gövdesinde ise sınıfın kendisidir:

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

Çıktı:

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

Görev

Kolay

Account sınıfında, 0'ın altındaki bir değer için ArgumentError yükselten ve balance cannot be negative mesajını veren özel bir setter balance= bulunur. initialize(owner, balance), deposit(amount) ve withdraw(amount) metotlarını, başlangıç bakiyesi de dâhil olmak üzere bakiyedeki her değişiklik bu setter üzerinden self. kullanılarak geçecek şekilde tamamla.

Sağlanan kod, sahibin adını ve başlangıç bakiyesini okur, ardından +n (para yatırma) veya -n (para çekme) komutlarını işler. Her komuttan sonra Ada: 120 çıktısını ya da hata mesajını ve değişmemiş bakiyeyi yazdırır. Geçersiz bir başlangıç bakiyesi yalnızca hata mesajını yazdırır.

Kodun account.rb dosyasına yazılmalıdır. main.rb sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

require_relative 'account'

# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
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 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