Ruby/Iteratory: Różnice pomiędzy wersjami
Usunięta treść Dodana treść
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.
Czasownik "iterować" oznacza wykonywać tę samą czynność wiele razy, tak więc iterator jest czymś co wykonuje tę samą rzeczy wiele razy.
<pre>
char *str;
for (str = "abcdefg"; *str != '\0'; str++) {
/*
}
</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:
<pre>
Linia 18:
for i in *.[ch]; do
# ...
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?
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.
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.
Typ ''String'' Rubiego posiada kilka użytecznych iteratorów:
<pre>
Linia 36:
</pre>
''each_byte''
<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.)
Another iterator of String is each_line.
|