Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

self في الأساليب

جزء من قسم البرمجة كائنية التوجه في رحلة Ruby على Coddy. الدرس 9 من 57.

داخل إحدى الطرق، يؤدي name = value دائمًا إلى إنشاء متغير محلي، حتى عندما يكون لدى الفئة مُعيِّن name=. لاستدعاء المُعيِّن، اكتب المُستقبِل: 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

الناتج:

level is a new local variable here, still nil
2

لا يحتاج القرّاء إلى self.: يستدعي كلٌّ من level وself.level الطريقة نفسها. يكتب الأسلوب المعتاد self. فقط حيث تحتاجه Ruby، أمام أداة ضبط:

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

الناتج:

24

يؤدي استدعاء أداة الضبط من initialize باستخدام self. إلى جعل الكائنات الجديدة تجتاز الفحص نفسه الذي تجتازه التغييرات اللاحقة، لذا تبقى القاعدة في مكان واحد:

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

الناتج:

5
price must be positive

يعتمد معنى self على مكان تشغيل الشيفرة. داخل طريقة مثيل، يكون هو المثيل؛ أما في نص الصنف، خارج كل طريقة، فيكون الصنف نفسه:

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

الناتج:

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

التحدي

سهل

يحتوي الصنف Account على مُعيِّن مخصص balance= يرفع ArgumentError مع balance cannot be negative عندما تكون القيمة أقل من 0. أكمل initialize(owner, balance) وdeposit(amount) وwithdraw(amount) بحيث يمر كل تغيير في الرصيد عبر ذلك المُعيِّن باستخدام self.، بما في ذلك الرصيد الابتدائي.

يقرأ الكود المُزوَّد اسم المالك والرصيد الابتدائي، ثم الأوامر +n (إيداع) أو -n (سحب). ويطبع Ada: 120 بعد كل أمر، أو رسالة الخطأ والرصيد غير المتغير. ويطبع الرصيد الابتدائي غير الصالح رسالة الخطأ فقط.

ضع الكود الخاص بك في account.rb. يحتوي main.rb على كود الإدخال/الإخراج المُزوَّد ولا يمكن تعديله.

جرّب بنفسك

require_relative 'account'

# كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
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 iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم Ruby عبر الإنترنت