المجموعات المخصصة
جزء من قسم البرمجة كائنية التوجه في رحلة Ruby على Coddy. الدرس 40 من 57.
يجمع صنف المجموعة عدة طرائق خاصة: each مع Enumerable، و<< للإضافة، وsize، وto_s وinspect للطباعة. ينبغي أن تعمل each أيضًا من دون كتلة، فتُعيد مُعدِّدًا باستخدام to_enum، كما تفعل المصفوفات:
class TodoList
include Enumerable
def initialize
@items = []
end
def <<(item)
@items << item
self
end
def each
return to_enum(:each) unless block_given?
@items.each { |item| yield item }
self
end
end
list = TodoList.new << "wash" << "shop" << "cook"
list.each.with_index(1) { |item, n| puts "#{n}. #{item}" }
p list.select { |i| i.include?("o") }الناتج:
1. wash
2. shop
3. cook
["shop", "cook"]تتحقق block_given? مما إذا كان المستدعي قد مرر كتلة. والمُعدِّد الذي يُعاد من دونها يدعم ربط الاستدعاءات، مثل each.with_index أو each_slice أو next:
class Countdown
include Enumerable
def initialize(from)
@from = from
end
def each
return to_enum(:each) unless block_given?
@from.downto(1) { |n| yield n }
end
end
e = Countdown.new(3).each
puts e.next
puts e.next
p Countdown.new(5).each_slice(2).to_aالمخرجات:
3
2
[[5, 4], [3, 2], [1]]to_s هو النص الودّي للمستخدمين، وinspect ملخّص قصير للمبرمجين. بالنسبة إلى مجموعة، يعرض inspect عادةً الصنف والحجم بدلًا من كل عنصر:
class TodoList
include Enumerable
def initialize(*items)
@items = items
end
def each(&block)
@items.each(&block)
end
def size
@items.size
end
def to_s
map.with_index(1) { |item, n| "#{n}. #{item}" }.join("\n")
end
def inspect
"#<TodoList #{size} items>"
end
end
list = TodoList.new("wash", "shop")
puts list
p listالناتج:
1. wash
2. shop
#<TodoList 2 عنصرين>توفر Enumerable الدالة count، ولكنها لا توفر size أو empty? أو << أو []: فهذه تنتمي إلى الصنف، لأنه وحده يعرف كيفية تخزين العناصر. ويجعل تعريفها المجموعة تبدو كأنها مصفوفة للجهات التي تستدعيها:
def size
@items.size
end
def empty?
@items.empty?
end
def [](index)
@items[index]
endالتحدي
سهلأكمل الصنف TodoList. يضيف << نص مهمة ويُرجع القائمة. يُنتج each المهام ويُرجع to_enum(:each) عند عدم تمرير كتلة. ضمّن Enumerable. يُرجع size عدد المهام. يُرجع to_s المهام في أسطر مرقّمة، 1. wash، أو nothing to do، ويُرجع inspect القيمة #<TodoList 3 items>.
يضيف الكود المرفق كل سطر من سطور الإدخال باستخدام تسلسل <<، ثم يطبع القائمة، ونتيجة p للقائمة، والمهام مرقّمة باستخدام ! عبر each.with_index(1) مثل 1! wash، وعدد المهام التي تحتوي على o، وأول مهمة أبجديًا.
ضع كودك في todo_list.rb. يحتوي main.rb على كود الإدخال والإخراج المرفق ولا يمكن تعديله.
جرّب بنفسك
require_relative 'todo_list'
# شيفرة الإدخال/الإخراج المقدَّمة: اتركها كما هي
input = []
while (line = gets)
input << line.chomp
end
list = input.reduce(TodoList.new) { |l, task| l << task }
puts list
p list
list.each.with_index(1) { |task, n| puts "#{n}! #{task}" }
puts "with o: #{list.count { |t| t.include?("o") }}"
puts "first: #{list.min}"
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الفئات والكائنات
العمل مع الملفاتتعريف الفئاتمتغيرات النسخةالأساليب و selfto_s و inspectمراجعة - بطاقة المكتبة7تعدد الأشكال والكتابة بأسلوب البطة
تعدد الأشكالالكتابة بأسلوب البطةالأساليب المجردةالحالات والفئاتمراجعة - طرق الدفع3أساليب ومتغيرات الأصناف
أساليب الأصنافمتغيرات كائنات الأصنافالثوابتأساليب الإنشاءمراجعة - رموز القسائمتدرّب بنفسك: مترجم Ruby عبر الإنترنت