Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: goto - opinie i przeżycia
Forum PHP.pl > Forum > PHP
adminik
Co sądzicie o goto np. jako zamiennikowi dla niektórych pętli?
Co sądzicie o elastyczności tego rozwiązania?

Chciałbym poznać kilka opinii na ten temat.

Mi osobiście przypadło goto do gustu.
darko
Unikaj jak ognia, tylko w ostateczności, jeśli wszystkie inne rozwiązania zawiodą (w php jeszcze mi się nie zdarzyło, żebym musiał skorzystać z goto). Etykiety i goto to raczej domena takich dinozaurów jak basic i pascal.
marcio
No co ty w ogole mowisz etykiety i skoki to mozna w asm'ie uzywac albo w epoce pascal'a.

Po to masz petle itp zeby je uzywac przy skokach pogubic sie mozna.

l0ud
W językach programowania wyższego poziomu takiej instrukcji nie powinno się stosować. Nie chciałbym być na miejscu osoby, która później taki kod ma przeanalizować, debugować (masa skoków nie wiadomo gdzie i nie wiadomo z czym). Zwłaszcza, że nie wnosi niczego, czego nie dałoby się zrobić za pomocą innych instrukcji...
Pilsener
A czy to nie działa przypadkiem tylko do przodu? Czy w obie strony? Znam to z podstaw VB, moim zdaniem może być niekiedy przydatne, a kiedy to już możemy sobie bajdurzyć. Zgodzę się w 100%, że nie należy w ten sposób budować pętli czy instrukcji warunkowych, ale np. rekurencja dla laików? Z goto czy bez każdy kod można totalnie spitolić.
darko
goto skacze do danej etykiety, a gdzie ją umieścisz, to już zależy od Ciebie. Rekurencja dla laików powiadasz. Hmm...
marcio
Cytat(Pilsener @ 5.01.2010, 23:26:40 ) *
A czy to nie działa przypadkiem tylko do przodu? Czy w obie strony? Znam to z podstaw VB, moim zdaniem może być niekiedy przydatne, a kiedy to już możemy sobie bajdurzyć. Zgodzę się w 100%, że nie należy w ten sposób budować pętli czy instrukcji warunkowych, ale np. rekurencja dla laików? Z goto czy bez każdy kod można totalnie spitolić.



Cytat(darko @ 5.01.2010, 23:28:56 ) *
goto skacze do danej etykiety, a gdzie ją umieścisz, to już zależy od Ciebie. Rekurencja dla laików powiadasz. Hmm...


Nie zrozumialem ironi uzytkownika @Pilsener.Jaka to roznica z goto czy petle/warunki rekurencja to rekurencja, to tak jakbym powiedzial ze latwiej jest napisac system news'ow strukturalnie niz obiektowo to jest jeden kit.


No chyba ze sie myle to zwracam honor.

XianN
Zostaw goto w spokoju. W manualu PHP dosc obrazowo jest pokazane dlaczego. Jesli jednak nie przekonuje Cie to zbytnio daj jakis przyklad dla ktorego jest to najlepsze wyjscie, a przymkne na moment oko dla zasady 'goto jest zawsze zle' ;-)
Cytat
This is not a full unrestricted goto. The target label must be within the same file and context, meaning that you cannot jump out of a function or method, nor can you jump into one. You also cannot jump into any sort of loop or switch structure. You may jump out of these, and a common use is to use a goto in place of a multi-level break.

  1. for($i=0,$j=50; $i<100; $i++) {
  2. while($j--) {
  3. if($j==17) goto end;
  4. }
  5. }
  6. echo "i = $i";
  7. echo 'j hit 17';


I wszystko spoko, ale jeszcze na dlugo przed PHP 5.3 (od ktorego goto jest dostepne, nie wiem w ogole po co...) mozna to zapisac 'poprawniej' uzywajac opcjonalnego argumentu dla konstrukcji break, ktory mowi z ilu petli chcemy wyskoczyc.
Cytat
break accepts an optional numeric argument which tells it how many nested enclosing structures are to be broken out of.

  1. for($i=0,$j=50; $i<100; $i++) {
  2. while($j--) {
  3. if($j==17) {
  4. echo 'j hit 17';
  5. break 2;
  6. }
  7. }
  8. }
Zyx
Jawna rekurencja to nienajciekawszy pomysł, ponieważ stos ma ograniczoną głębokość. Boli to zwłaszcza w PHP, gdzie możliwe jest zaledwie maksymalnie 100 zagnieżdżonych wywołań funkcji/metod. Istnieją sytuacje, w których goto jest jedynym w miarę sensownym sposobem pozbycia się rekurencji, np. gdy wywołanie znajduje się w pętli.

Kod
start_funkcji:
instrukcje
pętla()
{
   instrukcje

   // wywołanie rekurencyjne
   odloz_kontekst_na_wlasny_stos(kontekst);
   goto start_funkcji;
   powrot_z_funkcji:

   dalsze instrukcje
}

końcówka funkcji

// jeśli mamy nadrzędne wywołanie, wracamy do niego
kontekst = pobierz_kontekst_ze_stosu();
if(kontekst != null)
{
   rozpakuj_kontekst(kontekst);
   goto powrot_z_funkcji;
}


Niestety w PHP takie coś nie zadziała, ponieważ nie można wskakiwać do wnętrza pętli. Jednak jest to przykład kodu, kiedy z dwojga złego goto jest lepsze, bo alternatywna to stworzenie kilku wersji tej funkcji z powieloną większością kodu i na dokładkę napisanie algorytmu sterującego.
Cysiaczek
@Zyx - czy w php.ini nie da się zwiększyć limit dla wywołań? Nie pamiętam teraz dobrze, ale chyba coś takiego widziałem. Było to bodajże podyktowane koniecznością ochrony systemu (pamięć, czas wykonania).

Pozdrawiam
thek
Instrukcja GOTO miała jedyny sens w przypadku zagnieżdżenia wielopoziomowego. I to naprawdę jedyna jego obecnie forma używania. Ewentualnie stare języki skryptowe.
TheArt
Umiejętne stosowanie 'goto' jest bardzo przydatne.
Zyx
Cysiaczek -> w czystym PHP nie ma. XDebug dodaje odpowiednią opcję (xdebug.max_nesting_level), ale tego się raczej na serwerach produkcyjnych nie instaluje.
phpion
Cytat(TheArt @ 6.01.2010, 11:37:20 ) *
Umiejętne stosowanie 'goto' jest bardzo przydatne.

Bez urazy, ale tak mocno uzasadnioną wypowiedź autora tych tematów:
- http://forum.php.pl/index.php?showtopic=139112
- http://forum.php.pl/index.php?showtopic=139058
raczej nie można traktować poważnie.

PS: goto jest zupełnie zbędne - jedynym jego plusem jest to, że wprowadzi jeszcze więcej bałaganu w kodach początkujących programistów (w końcu to nowość języka! trzeba być trendy!), a co za tym idzie "starzy wyjadacze" będą rozpoznawani po braku goto winksmiley.jpg
ucho
Goto jest powszechnie stosowane w kernelu linuksowym. Z prostego powodu - nie ma żadnego RAII jak w c++ i konwencją jest skakanie do końca funkcji, gdzie znajduje się kod odpowiedzialny za zwalnianie zaalokowanej pamięci lub locków - nie da się po prostu użyć return. Ale po co to do PHP dodali nie mam pojęcia.

Edit:
Jeszcze przykład jak to mniej więcej tam wygląda (pseudokod)
  1. do A
  2. if (error)
  3. goto out_a;
  4. do B
  5. if (error)
  6. goto out_b;
  7. do C
  8. if (error)
  9. goto out_c;
  10. goto out;
  11. out_c:
  12. undo C
  13. out_b:
  14. undo B:
  15. out_a:
  16. undo A
  17. out:
  18. return ret;

Ktoś zaproponował żeby robić to tak :
  1. do A
  2. if (error) {
  3. cancel_a();
  4. return ret;
  5. }
  6. do B
  7. if (error) {
  8. cancel_b();
  9. cancel_a();
  10. return ret;
  11. }
  12. do C
  13. if (error) {
  14. cancel_c();
  15. cancel_b();
  16. cancel_a();
  17. return ret;
  18. }
  19. return ret;

To został prawie zlinczowany. Zresztą przy takiej wielkości projektu i braku namespace, już po kilka funkcji pomocniczych dla każdego kawałka kodu skończyło by się powstaniem nazw funkcji dłuższych niż te potworki z GTK smile.gif
deirathe
No tak, ale w phpie to raczej kernela pisac nie bedziesz...
Tak poza tym, poprawianie pozniej po kims kodu z intrukcjami goto to bedzie tragedia- juz lepiej odrazu z okna sobie skoczyc i zycie uproscic.
Goto w php jest totalnie zbedne, wprowadzi tylko wiecej zamieszania i pozwoli "programista" na tworzenie jescze wiekszego syfu z kodzie. Osobiscie jestem przeciwny
Pilsener
Obawiam się, że biorąc pod uwagę typowy sposób tworzenia stron przez ciała akademickie:
  1. echo $naglowek;
  2. echo $tresc;
  3. if($blad){die($blad);}
  4. echo $stopka;
- mogą łatwo zauważyć, że zastępując die goto da się wyświetlić błąd razem ze stopką biggrin.gif

Gdy akademicy dorwą się do goto i zaczną tego masowo używać do swoich machinacji możemy mieć trochę przegwizdane.

Na upartego można by tego użyć, gdy np. zachodzi konieczność zabicia kontrolera (krytyczny wyjątek) i przejścia do widoku, by pomijać określone fragmenty kodu ale tak naprawdę po co? Co zyskamy w zamian? Nawet stosując tradycyjną metodę obsługi błędów czy realizacji algorytmu zbudowanego na zasadzie drzewa:
  1. if(!$blad){$wykonaj = 'etap 1';}
  2. if(!$blad){$wykonaj = 'etap 1.1';}
  3. if(!$blad){$wykonaj = 'etap 1.2.';}
- uzyskujemy zapis wydajny a przede wszystkim czytelny, mamy też switch. By użyć goto trzeba by dodać do każdego warunku goto blad no i pojawia się kolejny problem, bo dochodzi rozmieszczanie etykiet, że już nie wspominając o czytelności czy kontroli nad kodem.

Jedyne sensowne zastosowanie tego potwora to cofanie się do jakiegoś kodu by go wykonać jeszcze raz, ale trudno mi wyobrazić sobie taką sytuację w praktyce, trzeba by projektować aplikację w zupełnie nowy sposób (pod goto), co pewnie mocno zirytowałoby całe środowisko programistów gdyby takie rozwiązania stały się popularne smile.gif Już widzę te publikacje typu nowoczesna obsługa sesji z wykorzystaniem goto biggrin.gif

Kedyś używałem goto w skryptach VB i z racji niskiego poziomu umiejętności przydawało się, gdy zaczynałem przygodę z PHP wydawało mi się, że będzie tego brakować smile.gif Kiedyś był tu taki temat "czego Wam brakuje w PHP" i napisałem tam, ze goto - doigrałem się, bo dodali, przepraszam Was za to blinksmiley.gif
erix
Cytat
- mogą łatwo zauważyć, że zastępując die goto da się wyświetlić błąd razem ze stopką

Hej, a nie po to wprowadzono wyjątki?

Cytat
Kiedyś był tu taki temat "czego Wam brakuje w PHP" i napisałem tam, ze goto - doigrałem się, bo dodali, przepraszam Was za to

Kto ma pasa? biggrin.gif

A teraz na serio - do tej pory nie mogę się nadziwić, po co wprowadzili goto. Naprawdę nie mogę tego pojąć - jakby nie było innych, WAŻNIEJSZYCH rzeczy do zaimplementowania...
l0ud
Zdaje się, że chcieli po prostu uczynić kodowanie w PHP jeszcze prostszym dla bardzo początkujących programistów, którzy budują stronę tak jak to napisał Pilsener tongue.gif Ew. ktoś uznał, że łatwo to zaimplementować a może się przydać w jakichś skrajnych sytuacjach, gdzie trzeba coś zmienić w skrypcie na 5 minut...
Crozin
@l0ud: IMO goto wcale nie jest dobre dla początkujących bo nagle program zaczyna skakać tam i z powrotem burząc prosty, liniowy przepływ kodu.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.