User Guide #09 - Ruby - iterators

interators, Ruby, ruby lesson, ruby уроки, user guide, итераторы, руководство пользователя

Iterators are not an original concept with ruby. They are in common use in object-oriented languages. They are also used in Lisp, though there they are not called iterators. However the concepet of iterator is an unfamiliar one for many so it should be explained in more detail.

The verb iterate means to do the same thing many times, you know, so an iterator is something that does the same thing many times.

When we write code, we need loops in various situations. In C, we code them using for or while. For example,

char *str;
for (str = "abcdefg"; *str != '\0'; str++) {
  /* process a character here */

C's for(...) syntax provides an abstraction to help with the creation of a loop, but the test of *str against a null character requires the programmer to know details about the internal structure of a string. This makes C feel like a low-level language. Higher level languages are marked by their more flexible support for iteration. Consider the following sh shell script:


for i in *.[ch]; do
  # ... here would be something to do for each file

All the C source and header files in the current directory are processed, and the command shell handles the details of picking up and substituting file names one by one. I think this is working at a higher level than C, don't you?

But there are is more to consider: while it is fine for a language to provide iterators for built-in data types, it is a disappointment if we must go back to writing low level loops to iterate over our own data types. In OOP, users often define one data type after another, so this could be a serious problem.

So every OOP language includes some facilities for iteration. Some languages provide a special class for this purpose; ruby allows us to define iterators directly.

Ruby's String type has some useful iterators:

ruby> "abc".each_byte{|c| printf "<%c>", c}; print "\n"

each_byte is an iterator for each character in the string. Each character is substituted into the local variable c. This can be translated into something that looks a lot like C code ...

ruby> s="abc";i=0
ruby> while i<s.length
    |    printf "<%c>", s[i]; i+=1
    | end; print "\n"

... however, the each_byte iterator is both conceptually simpler and more likely to continue to work even if the String class happens to be radically modified in the future. One benefit of iterators is that they tend to be robust in the face of such changes; indeed that is a characteristic of good code in general. (Yes, have patience, we're about to talk about what classes are, too.)

Another iterator of String is each_line.

ruby> "a\nb\nc\n".each_line{|l| print l}

The tasks that would take most of the programming effort in C (finding line delimiters, generating substrings, etc.) are easily tackled using iterators.

The for statement appearing in the previous chapter does iteration by way of an each iterator. String`s each works the same as each_line , so let's rewrite the above example with for :

ruby> for l in "a\nb\nc\n"
    |   print l 
    | end

We can use a control structureb retry in conjunction with an iterated loop, and it will retry the current iteration of the loop from the top.

ruby> c=0
ruby> for i in 0..4
    |   print i
    |   if i == 2 and c == 0
    |     c = 1
    |     print "\n"
    |     retry
    |   end
    | end; print "\n"

yield occurs sometimes in a definition of an iterator. yield moves control to the block of code that is passed to the iterator (this will be explored in more detail in the chapter about procedure objects). The following example defines an iterator repeat , which repeats a block of code the number of times specified in an argument.

ruby> def repeat(num)
    |   while num > 0
    |     yield
    |     num -= 1
    |   end
    | end
ruby> repeat(3) { print "foo\n" }

With retry, one can define an iterator which works the same as while, though it's too slow to be practical

ruby> def WHILE(cond)
    |   return if not cond
    |   yield
    |   retry
    | end
ruby> i=0; WHILE(i<3) { print i; i+=1 }
012   nil

Do you understand what an iterator is? There are a few restrictions, but you can write your original iterators; and in fact, whenever you define a new data type, it is often convenient to define suitable iterators to go with it. In this sense, the above examples are not terribly useful. We can talk about practical iterators after we have a better understanding of what classes are.

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
Support the author Donate


Only authorized users can post comments.
Please, Log in or Sign up

Hello, Dear Users of EVILEG!!!

If the site helped you, then support the development of the site financially, please.

You can do it by following ways:

Thank you, Evgenii Legotckoi

April 6, 2020, 5:24 a.m.

C++ - Test 001. The first program and data types

  • Result:86points,
  • Rating points6
April 5, 2020, 2:32 p.m.

C++ - Test 002. Constants

  • Result:91points,
  • Rating points8
April 5, 2020, 2:31 p.m.
Alexander Peshkov

C++ - Test 001. The first program and data types

  • Result:60points,
  • Rating points-1
Last comments
April 3, 2020, 8:06 a.m.
Konstantin Grudnitskiy

Я надеюсь вы уже разобрались в чем дело, но если вдруг нет, то проблема состоит в том, что вы пытаетесь запустить программу из интерпретатора питона. Файл это уже готова…
April 3, 2020, 6:18 a.m.
Konstantin Grudnitskiy

>>> text = 'hello world'>>> ' '.join(word for word in text.split()[:-1])'hello'>>> def remove_last_word(text):... return text and ' '.join(word for word in text.s…
March 27, 2020, 2:40 p.m.
Evgenij Legotskoj

Добрый день. В конце пятой статьи скачать можете.
March 27, 2020, 2:28 p.m.
mkdir _

Здравствуйте, а можно, пожалуйста, ссылку на целые исходники, если есть?
March 27, 2020, 4:36 a.m.
Evgenij Legotskoj

Скорее всего также, как и для установки всех остальных переменых в CMake, через использование set
Now discuss on the forum
April 6, 2020, 8:06 a.m.

Добрый день. Объясните пожалуйста ... ... допиливать стилевое оформление в прокси классе ... где именно копать ? В каком виртуальном методе лучше допиливать (если можно н…
April 6, 2020, 4:19 a.m.
Evgenij Legotskoj

Попробуй не переустанавливать материал, а просто менять цвет
April 5, 2020, 11:38 a.m.

Так работает windeployqt --qmldir E:\QTProject\testQmlAndCpp E:\test\build-testQmlAndCpp-Desktop_Qt_5_14_1_MinGW_32_bit-Release
April 5, 2020, 2:35 a.m.

Так работает console.log(textEmail.text) var str = textEmail.text; var n =^((([0-9A-Za-z]{1}[-0-9A-z\.]{1,}[0-9A-Za-z]{1})|([0-9А-Яа-я]{1}[-0-9А-я\.]{1,}[…
April 3, 2020, 8:48 a.m.

Евгений, добрый день. Спасибо!
© EVILEG 2015-2019
Recommend hosting TIMEWEB