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

أساليب المعاملات

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

معظم عوامل Ruby هي أساليب. يستدعي a + b الدالة a.+(b)، لذا يعرّف الصنف + مثل أي أسلوب آخر. تُرجع العمليات الحسابية على كائنات القيم كائنًا جديدًا وتترك كلا المعاملين دون تغيير:

class Vector
  attr_reader :x, :y

  def initialize(x, y)
    @x = x
    @y = y
  end

  def +(other)
    Vector.new(x + other.x, y + other.y)
  end

  def to_s
    "(#{x}, #{y})"
  end
end

a = Vector.new(1, 2)
b = Vector.new(3, 4)
puts a + b
puts a

الناتج:

(4, 6)
(1, 2)

يمكن أن تكون المعامِلة اليمنى نوعًا آخر من القيم، مثل رقم لإجراء التحجيم. السالب الأحادي هو الطريقة -@:

class Vector
  attr_reader :x, :y

  def initialize(x, y)
    @x = x
    @y = y
  end

  def -(other)
    Vector.new(x - other.x, y - other.y)
  end

  def *(factor)
    Vector.new(x * factor, y * factor)
  end

  def -@
    Vector.new(-x, -y)
  end

  def to_s
    "(#{x}, #{y})"
  end
end

v = Vector.new(3, 4)
puts v * 2
puts v - Vector.new(1, 1)
puts(-v)

الناتج:

(6, 8)
(2, 3)
(-3, -4)

بمجرد وجود +، يعمل += أيضًا، لأن a += b تعني a = a + b. تعمل sum أيضًا عند إعطائها قيمة ابتدائية من فئتك:

class Money
  attr_reader :cents

  def initialize(cents)
    @cents = cents
  end

  def +(other)
    Money.new(cents + other.cents)
  end

  def to_s
    format("$%.2f", cents / 100.0)
  end
end

total = Money.new(0)
total += Money.new(250)
total += Money.new(199)
puts total
puts [Money.new(100), Money.new(5)].sum(Money.new(0))

الناتج:

$4.49
$1.05

<=> هو عامل أيضًا. وبالاشتراك مع Comparable، يتيح مقارنة كائنات Money وترتيبها، ويمكن للعامل رفض مُعامل غير متوافق من خلال رفع استثناء، كما تفعل الأعداد:

class Money
  include Comparable
  attr_reader :cents, :currency

  def initialize(cents, currency)
    @cents = cents
    @currency = currency
  end

  def +(other)
    raise ArgumentError, "cannot add #{other.currency} to #{currency}" unless other.currency == currency

    Money.new(cents + other.cents, currency)
  end

  def <=>(other)
    cents <=> other.cents
  end
end

puts Money.new(500, "EUR") > Money.new(300, "EUR")
begin
  Money.new(1, "EUR") + Money.new(1, "USD")
rescue ArgumentError => e
  puts e.message
end

الناتج:

true
cannot add USD to EUR
challenge icon

التحدي

سهل

أكمل الصنف Vector. عرّف + و- لمتجهين، و* لمتجه وعدد، والسالب الأحادي -@، و== لمقارنة الإحداثيين معًا، وto_s، الذي يعيد (4, 6). تُعيد length طول المتجه باستخدام Math.sqrt.

يقرأ الكود المزوّد تعبيرات: 1,2 + 3,4، و1,2 - 3,4، و1,2 * 3، وneg 1,2، و1,2 == 1,2. ويطبع كل نتيجة، وبالنسبة إلى نتائج المتجهات يطبع أيضًا length 7.21 بمنزلتين عشريتين.

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

جرّب بنفسك

require_relative 'vector'

# كود الإدخال/الإخراج المُزوَّد: اتركه كما هو
input = []
while (line = gets)
  input << line.chomp
end
def vec(text)
  Vector.new(*text.split(",").map(&:to_i))
end

input.each do |line|
  parts = line.split
  result = if parts[0] == "neg" then -vec(parts[1])
           else
             a = vec(parts[0])
             case parts[1]
             when "+" then a + vec(parts[2])
             when "-" then a - vec(parts[2])
             when "*" then a * parts[2].to_i
             else a == vec(parts[2])
             end
           end
  puts result
  puts format("length %.2f", result.length) if result.is_a?(Vector)
end
quiz iconاختبر نفسك

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

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

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