Ruby/Iteratory: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
Kj (dyskusja | edycje)
m +nav
Szymon wro (dyskusja | edycje)
Nie podano opisu zmian
Linia 1:
Iteratory nie są oryginalnym pojęciem Rubiego. Są one w powszechnym użyciu w językach zorientowanych obiektowo. Występują również w Lispie, choć nie są tam nazywane iteratorami. Jednakże koncepcja iteratorów jest wielu osobom obca, więc tutaj zostanie one wyjaśniona nieco bardziej szczegółowo.
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.
 
Czasownik "iterować" oznacza wykonywać tę samą czynność wiele razy, tak więc iterator jest czymś co wykonuje tę samą rzeczy wiele razy.
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.
 
WhenPodczas wepisania writekodu code,potrzebujemy wepętli needw loopswielu inróżnych various situationssytuacjach. InW C, we codekodujemy themje usingużywając ''for'' orlub ''while''. ForNa exampleprzykład,
 
<pre>
char *str;
for (str = "abcdefg"; *str != '\0'; str++) {
/* processtutaj aprzetwarzamy character hereznak */
}
</pre>
 
Składnia pętla ''for(...)'' z języka C dostarcza pewnej abstrakcji, która pomaga w utworzeniu pętli, ale sprawdzenie czy ''*str'' nie wskazuje na znak pusty znak wymaga od programisty znajomości szczegółów o wewnętrznej strukturze łańcucha znakowego. Sprawia to, że C jest odczuwany jako język niskiego poziomu. Języki wyższego poziomu odznaczają się bardziej elastycznym wsparciem iteracji. Rozważ następujący skrypt ''sh'' powłoki systemowej:
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:
 
<pre>
Linia 18:
 
for i in *.[ch]; do
# ... heretutaj wouldbyłby bekod somethingdo to dowykonania fordla eachkażdego filepliku
done
</pre>
 
Wszystkie pliki źródłowe i nagłówkowe języka C w bieżącym katalogu są przetwarzane i powłoka systemowa bierze na siebie detale dotyczące wskazywania i podstawiania po kolei wszystkich nazw plików, jedna po drugiej. To chyba działa na wyższym poziomie niż C, nie sądzisz?
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?
 
Trzeba zauważyć jeszcze więcej: często język dostarcza iteratorów dla typów wbudowanych, ale rozczarowuje gdy okazuje się, że musimy wracać z powrotem do pętli nisko poziomowych by iterować nasze własne typy danych. W programowaniu zorientowanym obiektowo (OOP - ang. Object-Oriented Programming), użytkownicy zazwyczaj definiują własne typy danych jeden za drugim, więc to może być całkiem poważnym problemem.
But there 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.
 
Tak więc każdy język wspierający OOP zawiera jakieś udogodnienia do iterowania. Niektóre języki dostarczają w tym celu specjalnych klas; Ruby pozwala na definiowanie iteratorów bezpośrednio.
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.
 
Typ ''String'' Rubiego posiada kilka użytecznych iteratorów:
Ruby's String type has some useful iterators:
 
<pre>
Linia 36:
</pre>
 
''each_byte'' is anto iterator forwskazujący eachna characterkażdy inznak thew stringłańcuchu. EachKażdy characterznak isjest substitutedpodstawiany intodo thezmiennej local variablelokalnej ''c''. ThisTo cansamo bemożna translatedprzełożyć intona somethingcoś thatbardziej looksprzypominającego a lot likekod C code ...
 
<pre>
Linia 48:
</pre>
 
... jednakże, iterator ''each_byte'' jest koncepcyjnie prostszy, jak i wydaje się, że działałby nadal nawet gdyby klasa ''String'' uległa w przyszłości radykalnym modyfikacjom. Dużą zaletą iteratorów jest to, że zachowują one swoje poprawne działanie na przekór takim radykalnym zmianom; i w rzeczy samej, jest to charakterystyczna cecha dobrego kodu w ogólności. (Tak, miej cierpliwość, niebawem będziemy mówić również o tym czym są klasy.)
... 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.