Przejdź do zawartości

Perl/Pętle

Z Wikibooks, biblioteki wolnych podręczników.
Poprzedni rozdział: Instrukcja kontrolna if
Następny rozdział: Operacje na plikach

Pętle

[edytuj]

Pętle jak sama nazwa wskazuje "zapętlają" pewną część kodu. Ułatwiają nam pracę gdy np. chcemy coś zrobić na wszystkich elementach w tablicy. Perl posiada kilka rodzajów pętli, które nie różnią się znacznie od tych, które są w C, czy Javie. W składni każdej pętli opcjonalnie istnieje etykieta. W skład etykiety wchodzi nazwa (przyjęło, się aby była pisana wielkimi literami) oraz dwukropek.

While i until

[edytuj]

Składnia pętli wygląda następująco:

ETYKIETA: while (wyrażenie logiczne) {
  instrukcje
}

Instrukcje zawarte w pętli while są wykonywane, dopóki wyrażenie logiczne jest prawdziwe. Czyli, jeśli na samym początku wyrażenie to nie jest prawdziwe, to instrukcje zawarte w pętli nie zostaną wykonane ani razu.

Pętla until neguje sens wyrażenia logicznego. Jest wykonywana dotąd dopóki wyrażenie jest fałszywe.

Pętle while i until jeżeli tego zechcemy mogą posiadać blok continue:

ETYKIETA: while (wyrażenie logiczne) {
  instrukcje
} continue {
  instrukcje
}

Instrukcje zawarte w tym bloku są wykonywane po skończeniu bloku pierwszego lub po użyciu operatora next omówionego w dalszej części tego rozdziału.

Oto prosta pętla wypisująca liczby od 0 do 100:

my $n = 0;
while ($n <= 100) {
  print $n++, "\n";
}

Pętle do {} while i do {} until są technicznie modyfikatorami i tak naprawdę nie są strukturami sterującymi.

do {
    instrukcja
} while (wyrażenie logiczne);
do {
    instrukcja
} until (wyrażenie logiczne);

For i foreach

[edytuj]

Słowa kluczowe for i foreach są synonimami i mogą być używane zamienne. Pamiętaj jednak, że w dobrym stylu programowania jest aby używać słowa foreach dla pętli pobierającej wartości z listy, zaś for dla pętli zawierających warunki.

ETYKIETA: foreach zmienna ( tablica ) {
    instrukcje
}

Pętla for wykonuje instrukcje dla każdej zmiennej w tablicy. Aktualny element jest przechowywany w zmiennej. zmienna jest aliasem do każdego elementu w tablicy, idzie kolejno od pierwszego elementu poprzez pętlę. Pętla jest zakończana, jeśli każdy element został uwzględniony. Ponieważ zmienna jest aliasem, zmieniając jego wartość będziemy zmieniać zawartość tablicy. Nie wolno tego robić, gdyż utrudnia to wychwytywanie błędów. Jeśli zmienna nie zostanie wpisana w kodzie programu, domyślnie zostanie użyta zmienna $_.

@tablica = ('dziwnie', 'wypisany', 'napis');
foreach (@tablica) {
  print "$_\n";
}
Przepisz kod powyżej i zobacz jak on działa.

Istnieją dwa sposoby użycia pętli for/foreach. Pierwszy już poznaliśmy, oto następny.

ETYKIETA: for (inicjalizacja; warunek zakończenia; wyrażenie inkrementujące) {
    instrukcje
}

Składa się ona z trzech wyrażeń rozdzielonych średnikami. Wszystkie są opcjonalne (oprócz średników), a domyślną wartością pętli jest prawda (więc bez wyrażeń pętla jest nieskończona).

Oto kolejna prosta pętla wypisująca liczby od 0 do 10:

for ($n = 0; $n <= 10; $n++) {
  print "$n\n";
} 

W dobrym stylu jest deklarowanie zmiennych w pętli, stają się one wówczas zmiennymi lokalnymi. Unikamy też w ten sposób przypadkowego nadpisania zmiennych o takich samych nazwach dostępnych wewnątrz funkcji, lub w cały programie. Uważaj na wcześniejsze niż obecna wersje perla pod Windows, taka konstrukcja była traktowana jako błąd. Obecnie nie ma tego problemu. Przykłady:

for (my $n = 0; $n <= 10; $n++) {
  print "$n\n";
} 
foreach my $n (@tablica) {
  print "$n\n";
}

Operatory sterujące pętlą

[edytuj]

W perlu mamy następujące operatory; next, redo, last oraz goto.

next

[edytuj]

next powoduje przejście do następnej iteracji, nie zakończając aktualnej. Można go używać razem z etykietą albo bez niej. Jeżeli pętla zawiera blok continue to jest on wykonywany.

my @tablica = ('dziwnie', 'wypisany', 2, 'napis');
for (@tablica) {
  if (/\d+/) {
    next;
  }
  print "$_\n";
} continue {
  print "po kolejnej iteracji\n";
}

/\d+/ jest wyrażeniem regularnym, zwraca prawdę gdy odnajdzie cyfrę. Ale o tym dalej w podręczniku.

Przepisz ten program i uruchom. Teraz powinieneś już rozumieć operator next.

last

[edytuj]

last powoduje opuszczenie bieżącej pętli. Blok continue nie jest wykonywany.

my @linie = ("jakiś tekst\n", "następna linia\n", "KONIEC\n", "inny fragment\n");
my $ile = 0;
for (@linie) {
  if (/^KONIEC/) {
    print "To już jest koniec...\n";
    last;
  }
  print;
} continue {
  print 'Zostałem wyświetlony po raz ', ++$ile, "\n";
}

Pętla pobiera elementy z tablicy i wyświetla je dopóki nie natrafi na napis "KONIEC" na początku lini (tak to też jest wyrażenie regularne).

Zastanów się co wyświetli ten program, a następnie uruchom go.

redo

[edytuj]

redo ponownie wykonuje tę samą pętlę, nie sprawdzając warunku. Nie wykonuje bloku continue.

goto

[edytuj]

goto powoduje natychmiastowy przeskok w inne wskazane miejsce w kodzie. np:

goto trzy;
jeden:
print "world\n";
goto koniec;
dwa:
print "hello ";
goto jeden;
trzy:
print "napis ";
goto dwa;
koniec:

Powyższy program wyświetli tekst: "napis hello world". Jak łatwo się domyślić jest dużo znacznie łatwiejszych sposobów na wykonanie tego zadania.

Używanie tej komendy nie jest zalecane ze względu na duże gmatwanie kodu oraz łatwą zastępowalność innymi strukturami programistycznymi.

Poprzedni rozdział: Instrukcja kontrolna if
Następny rozdział: Operacje na plikach