الصنف Enumerator
في روبي
الصنف Enumerator
هو صنفٌ يسمح بتنفيذ عملية التكرار الداخلي والخارجي على الكائنات. يمكن إنشاء كائنات من هذا الصنف باستعمال إحدى التوابع التالية: Kernel.to_enum
، أو Kernel.enum_for
، أو new
.
أغلب التوابع في هذا الصنف تملك شكلين هما: الشكل الكتلي (block form) الذي تقيَّم فيه المحتويات لكل عنصر في المجموعة التعدادية، والشكل الغير كتلي (non-block form) الذي يعيد كائنًا جديدًا من النوع Enumerator
يغلِّف التكرار.
enumerator = %w(one two three).each
puts enumerator.class # => Enumerator
enumerator.each_with_object("foo") do |item, obj|
puts "#{obj}: #{item}"
end
# foo: one
# foo: two
# foo: three
enum_with_obj = enumerator.each_with_object("foo")
puts enum_with_obj.class # => Enumerator
enum_with_obj.each do |item, obj|
puts "#{obj}: #{item}"
end
# foo: one
# foo: two
# foo: three
هذا يسمح لك بربط الكائنات Enumerator
مع بعضها بعضًا. على سبيل المثال، يمكنك تحويل كل عنصر من عناصر قائمة إلى سلسلة نصية تحوي الفهرس والعنصر بالشكل التالي:
puts %w[foo bar baz].map.with_index { |w, i| "#{i}:#{w}" }
# => ["0:foo", "1:bar", "2:baz"]
يمكن أيضًا استعمال الصنف Enumerator
كمكرِّر داخلي. على سبيل المثال، يعيد التابع next
القيمة التالية للمكرِّر أو يطلق الاستثناء StopIteration
إن وصل الكائن Enumerator
إلى النهاية.
e = [1,2,3].each # returns an enumerator object.
puts e.next # => 1
puts e.next # => 2
puts e.next # => 3
puts e.next # raises StopIteration
يمكنك استعمال هذا المثال لتنفيذ تكرار داخلي بالشكل التالي:
def ext_each(e)
while true
begin
vs = e.next_values
rescue StopIteration
return $!.result
end
y = yield(*vs)
e.feed y
end
end
o = Object.new
def o.each
puts yield
puts yield(1)
puts yield(1, 2)
3
end
# use o.each as an internal iterator directly.
puts o.each {|*x| puts x; [:b, *x] }
# => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
# convert o.each to an external iterator for
# implementing an internal iterator.
puts ext_each(o.to_enum) {|*x| puts x; [:b, *x] }
# => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
توابع الصنف العامة
new
ينشئ كائنًا جديدًا من النوع Enumerator
يمكن استعماله ككائن قابل للتعداد (Enumerable).
توابع النسخة العامة
each
يتكرر عبر الكتلة المعطاة وفقًا للكائن المُعدِّد الذي استدعي معه والطريقة التي أُنشِئ بها.
each_with_index
يشبه التابع with_index
باستثناء أنه لا يوجد إزاحة بادئة لبدء العملية عند قيمة محدَّدة.
each_with_object
يكرر الكتلة المعطاة على كل عنصر من عناصر الكائن الذي استدعي معه مع كائن آخر اعتباطي (الكائن المُمرَّر إليه).
feed
يضبط القيمة المراد إعادتها عبر الاستدعاء yield
التالي داخل e
.
inspect
ينشئ نسخةً قابلةً للطباعة من e.
next
يعيد الكائن التالي في المُعدِّد الذي استدعي معه، ويحرك موضع المؤشر الداخلي للأمام خطوة واحدة.
next_values
يعيد مصفوفة تحوي الكائن التالي في المُعدِّد الذي استدعي معه، ويحرك موضع المؤشر الداخلي للأمام خطوةً واحدةً.
peek
يعيد الكائن التالي في المُعدِّد الذي استدعي معه ولكن لا يحرِّك موضع المؤشر الداخلي للأمام.
peek_values
يعيد مصفوفة تحوي القيمة التالية في المُعدِّد الذي استدعي معه بشكل مشابه للتابع next_values
ولكن لا يحرِّك موضع المؤشر الداخلي للأمام.
rewind
يعيد موضع مؤشر السلسلة التعدادية (enumeration sequence) إلى البداية.
size
يعيد حجم المُعدِّد الذي استدعي معه، أو يعيد القيمة nil
إن لم يكن بالإمكان حساب الحجم بالنمط الكسول (lazily).
with_index
يكرر الكتلة المعطاة على كل عنصر من عناصر المُعدِّد الذي استدعي معه مع فهارسها والتي تبدأ عند موضع محدَّد.
with_object
يكرر الكتلة المعطاة على كل عنصر من عناصر المُعدِّد الذي استدعي معه مع كائن اعتباطي (الكائن المُمرَّر إليه) ثم يعيد هذا الكائن.