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

من موسوعة حسوب
مراجعة 12:59، 16 ديسمبر 2018 بواسطة جميل-بيلوني (نقاش | مساهمات) (إنشاء الصفحة.)
(فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)

الصنف 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

توابع الصنف العامة

توابع النسخة العامة

مصادر