الصنف 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
في بعض الحالات، تستبدل هذه الأصناف التوابع المعرَّفة في هذا الصنف.
لفهم سلوك أنواع محدَّدة من الأعداد، انتقل إلى التوثيق المخصص بهم واطَّلع عليه.