الحالات والفئات
جزء من قسم البرمجة كائنية التوجه في رحلة Ruby على Coddy. الدرس 35 من 57.
يمكن لـ case التفرّع اعتمادًا على فئة قيمة ما. يطابق when Integer كل عدد صحيح، لأن case يقارن باستخدام ===، وInteger === 5 يسأل عمّا إذا كان 5 من نوع Integer (is_a?):
def describe(value)
case value
when Integer then "integer #{value}"
when Float then format("float %.2f", value)
when String then "text of #{value.size} chars"
when nil then "nothing"
else "other: #{value.class}"
end
end
[5, 2.5, "hi", nil, [1, 2]].each { |v| puts describe(v) }الناتج:
integer 5
float 2.50
text of 2 chars
nothing
other: Arrayلأن === في الصنف يتبع is_a?، فإن when الذي يحتوي على صنف فائق يطابق أصنافه الفرعية أيضًا. رتّب الفروع من الصنف الأكثر تخصيصًا إلى الأكثر عمومية:
class Animal
end
class Dog < Animal
end
def kind(x)
case x
when Dog then "a dog"
when Animal then "some animal"
else "not an animal"
end
end
puts kind(Dog.new)
puts kind(Animal.new)
puts kind("Rex")
puts Animal === Dog.newالناتج:
a dog
some animal
not an animal
trueيمكن لكتلة when واحدة أن تسرد عدة أصناف، ويمكن للفروع تنفيذ عمل فعلي باستخدام القيمة، مثل حساب مجموع بنية متداخلة من أنواع مختلطة:
def total(value)
case value
when Integer, Float then value
when String then value.to_f
when Array then value.sum { |v| total(v) }
when Hash then total(value.values)
else 0
end
end
puts total([1, "2.5", { a: 3, b: [4, nil] }])الناتج:
10.5التفرّع حسب الفئات يناسب القيم التي لا يمكنك منح فئاتها أساليب جديدة، مثل الأعداد والسلاسل والمصفوفات، أو البيانات الواردة من الخارج. أما بالنسبة إلى فئاتك الخاصة، ففضّل تعدد الأشكال: إذ تحتاج الفئة الجديدة حينها إلى أسلوب جديد، لا إلى فرع جديد في كل case:
# فئاتك الخاصة: دع كل واحدة يجيب
shape.area
# القيم المدمجة من الخارج: تفرع حسب الفئة
case value
when Integer then ...
when String then ...
endالتحدي
سهلأكمل الدالة المساعدة describe(value) في functions.rb باستخدام case على فئة القيمة. تُرجع integer 5 (odd) أو integer 4 (even)، وfloat 2.50 بمنزلتين عشريتين، وtext "hi" (2 chars)، وlist of 3: 1, a, 2.5 (مع ضمّ العناصر بعد تحويلها باستخدام to_s)، وnothing للقيمة nil، وother Symbol لأي قيمة أخرى. الرموز هي النوع الآخر الوحيد الموجود في الاختبارات.
يحوّل الكود المُ supplied كل سطر إدخال إلى قيمة (أعداد صحيحة، وكسور عشرية، وقوائم [a,b]، وnil، ورموز :name، أو نص) ويطبع describe لكل قيمة.
ضع الكود الخاص بك في functions.rb. يحتوي main.rb على كود الإدخال/الإخراج المُ supplied ولا يمكن تعديله.
جرّب بنفسك
require_relative 'functions'
# كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
input = []
while (line = gets)
input << line.chomp
end
def parse(text)
return Integer(text) if text.match?(/\A-?\d+\z/)
return Float(text) if text.match?(/\A-?\d+\.\d+\z/)
return nil if text == "nil"
return text[1..].to_sym if text.start_with?(":")
return text[1...-1].split(",").map { |t| parse(t) } if text.start_with?("[")
text
end
input.each { |line| puts describe(parse(line)) }
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الفئات والكائنات
العمل مع الملفاتتعريف الفئاتمتغيرات النسخةالأساليب و selfto_s و inspectمراجعة - بطاقة المكتبة7تعدد الأشكال والكتابة بأسلوب البطة
تعدد الأشكالالكتابة بأسلوب البطةالأساليب المجردةالحالات والفئاتمراجعة - طرق الدفع3أساليب ومتغيرات الأصناف
أساليب الأصنافمتغيرات كائنات الأصنافالثوابتأساليب الإنشاءمراجعة - رموز القسائمتدرّب بنفسك: مترجم Ruby عبر الإنترنت