الصنف Numeric في روبي

من موسوعة حسوب

الصنف Numeric هو الصنف الذي يجب أن ترثه كل الأصناف العددية عالية المستوى.

يسمح الصنف Numeric بتمثيل (instantiation) الكائنات المحجوزة في الكومة (heap-allocated objects). تُنفَّذ الأصناف العددية الأساسية الأخرى، مثل Integer، كأصناف آنيَّة، أي أنّ كل عدد صحيح هو كائن غير قابل للتغيير (immutable)، والذي يُمرَّر دائمًا بقيمته. اطلع على المثال التالي:

a = 1
1.object_id == a.object_id   #=> true

لا يمكن أن يكون هناك إلا نسخة (instance) واحدة فقط من العدد الصحيح 1. تضمن روبي بهذا منع إنشاء نسخ جديدة ومنع التكرار.

Integer.new(1)   #=> NoMethodError: undefined method `new' for Integer:Class
1.dup            #=> TypeError: can't dup Integer

لهذا السبب، يجب استخدام الصنف Numeric عند تعريف أصناف عددية أخرى.

يجب أن تنفِّذ الأصناف التي ترث من الصنف Numeric التابع coerce، والذي يعيد مصفوفة بعنصرين تحتوي على كائن مُحوّل (coerced) إلى نسخة من الصنف الجديد والكائن self (انظر توثيق التابع coerce).

يجب أيضا على الأصناف الوراثة أن تنفِّذ معاملات العمليات الحسابية (+ ، - ، * و /) والمعامل <=> (انظر الصنف Comparable). قد تعتمد هذه التوابع على التابع coerce لضمان إمكانية التداخل (interoperability) مع نسخ الأصناف العددية الأخرى.

class Tally < Numeric
  def initialize(string)
    @string = string
  end

  def to_s
    @string
  end

  def to_i
    @string.size
  end

  def coerce(other)
    [self.class.new('|' * other.to_i), self]
  end

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

  def +(other)
    self.class.new('|' * (to_i + other.to_i))
  end

  def -(other)
    self.class.new('|' * (to_i - other.to_i))
  end

  def *(other)
    self.class.new('|' * (to_i * other.to_i))
  end

  def /(other)
    self.class.new('|' * (to_i / other.to_i))
  end
end

tally = Tally.new('||')
puts tally * 2            #=> "||||"
puts tally > 1            #=> true

توابع النسخ العامة (Public Instance Methods)

modulo

يعيد باقي قسم عدد على آخر.

+

يمثِّل المعامل + الأحادي إشارة الزائد التي تسبق العدد لتشير إلى أنه عدد موجب.

-

يمثِّل المعامل - الأحادي إشارة الناقص التي تسبق العدد لتشير إلى أنه عدد سالب.

<=>

يوازن المعامل <=> بين عددين ثمَّ يعيد القيمة 0 إن كان هذان العددان متساويين، وإلا فسيُعيد القيمةnil.

abs

يعيد القيمة المطلقة للعدد الذي استُدعي معه.

abs2

يعيد مربع العدد الذي استُدعي معه.

angle

يعيد القيمة 0 إن كان العدد الذي استُدعي معه موجبًا، أو القيمة pi خلاف ذلك.

arg

يعيد القيمة 0 إن كان العدد الذي استُدعي معه موجبًا، أو القيمة pi خلاف ذلك.

ceil

يعيد أصغر عدد من الأعداد الأكبر من أو تساوي العدد الذي استُدعي معه وبدقة محدَّدة.

clone

يعيد الكائن الذي استُدعي معه.

coerce

إن كان العدد المُمرَّر إلى التابع numeric من نفس نوع العدد الذي استُدعي معه، فسيعيد مصفوفة تحوي هذين العددين. خلاف ذلك، سيحول هذين العددين إلى النوع Float ويعيدهما في مصفوفة.

conj

يعيد الكائن الذي استُدعي معه (الكائن self).

conjugate

يعيد الكائن الذي استُدعي معه (الكائن self).

denominator

يعيد المقام (denominator) للعدد الكسري الذي استدعي معه، ويكون دائمًا موجبًا.

div

يستخدم المعامل / لإجراء عملية القسمة على العددين المعطيين، ثم يحوّل النتيجة إلى عدد صحيح.

divmod

يعيد مصفوفة تحتوي على حاصل (quotient) وباقي قسمة العدد الذي استُدعي معه على العدد المُمرَّر إليه.

dup

يعيد الكائن الذي استُدعي معه.

eql?‎

يتحقق إن كان العدد الذي استُدعي معه والعدد المُمرَّر إليه من نفس النوع ومتساويين.

fdiv

يجري عملية القسمة بين العدد الذي استدعي معه والعدد الذي مُرِّر إليه ثم يعيد الناتج في عدد عشري.

?finite

يتحقق إن كان العدد الذي استُدعي معه عددًا منتهيًا (finite).

floor

يعيد أكبر عدد من الأعداد الأصغر من أو تساوي العدد الذي استُدعي معه وبدقة محدَّدة.

i

يعيد العدد التخيلي (imaginary number) المقابل للعدد الذي استدعي معه.

imag

يعيد الصفر.

imaginary

يعيد الصفر.

infinite?‎

يتحقق إذا ما إن كان العدد الذي استدعي معه منتهيًا (finite) أو غير منتهي من الطرف السالب (‎-Infinity) أو غير منتهي من الطرف الموجب (‎+Infinity).

integer?‎

يتحقق إن كان العدد الذي استُدعي معه من النوع Integer.

magnitude

يعيد القيمة المطلقة للعدد الذي استُدعي معه.

modulo

يعيد باقي قسم عدد على آخر.

?negative

يتحقق إن كان العدد الذي استُدعي معه عددًا سالبًا.

?nonzero

يعيد العدد الذي استُدعي معه إن كان غير صفري، أو يعيد القيمة nil خلاف ذلك.

numerator

يعيد البسط (numerator) للعدد الكسري الذي استدعي معه.

phase

يعيد القيمة 0 إن كان العدد الذي استُدعي معه موجبًا، أو يعيد القيمة pi خلاف ذلك.

polar

يعيد المصفوفة [num.abs، num.arg]، إذ num هو العدد الذي استدعي معه.

?positive

يتحقق إن كان العدد الذي استُدعي معه عددًا موجبًا.

quo

يعيد ناتج القسمة الأكثر دقة (قيمة جذرية للأعداد الصحيحة، وقيمة عشرية للأعداد العشرية).

real

يعيد العدد الذي استدعي معه (الكائن self).

real?‎

يتحقق إن كان العدد الذي استُدعي معه عددًا حقيقيًّا (أي ليس من النوع Complex).

rect

يعيد المصفوفة [num, 0] إذ num يمثل العدد الذي استُدعي معه.

rectangular

يعيد المصفوفة [num, 0] إذ num يمثل العدد الذي استُدعي معه.

remainder

يعيد باقي قسم عدد على آخر. أي عندما يُستدعَى التابع بالشكل x.remainder(y)‎، فإنه يماثل الاستدعاء x-y*(x/y).truncate.

round

يقرِّب العدد الذي استُدعي معه إلى أقرب قيمة بدقة محدَّدة.

step

يستدعي الكتلة المعطاة مع تمرير سلسلة من الأعداد إليها بدءًا من العدد الذي استُدعي معه وحتى قيمة محدَّدة مع الزيادة أو الطرح بقدار خطوة ثابتة معطاة.

to_c

يحول العدد الذي استُدعي معه إلى عدد عقدي.

to_int

يستدعي التابع to_i الخاص بالصنف الفرعي (child class) لتحويل العدد الذي استُدعي معه إلى عدد صحيح.

truncate

يعيد التابع truncate العدد الذي استُدعي معه بعد اقتطاع المنازل العشرية منه بمقدار محدَّد.

zero?‎

يتحقق إن كانت قيمة العدد الذي استُدعي معه تساوي الصفر.

ملاحظات إضافية

الصنف Numeric هو صنفٌ أساسيٌ لأنواع الكائنات الأخرى العددية. اطلع مثلًا على الشيفرة التالية:

puts 100.class         # Fixnum
puts (100.2).class     # Float
puts (100**100).class  # Bignum

في بعض الحالات، تستبدل هذه الأصناف التوابع المعرَّفة في هذا الصنف.

لفهم سلوك أنواع محدَّدة من الأعداد، انتقل إلى التوثيق المخصص بهم واطَّلع عليه.

مصادر