- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
sub save_info {
beginTransaction();
#------- 250 строк страшного кода, типа: ---------
.....
goto ERROR if $error_code != 0;
.....
#------- или
if ( $res = save_item($data) ) {
goto OK;
}
............
#------- Но конец просто меня убил!!! ---------
OK:
commitTransaction();
goto RET;
ERROR:
rollbackTransaction();
RET:
return $res;
}
Я около 3 лет пишу на perl. И догадывался, что есть perl-программисты, которые используют оператор goto LABEL.
Но я никогда не думал, что мне придется саппортить их код!!!
Удобно переучиваться на Перл после Ассемблера :))
Надо только пользоваться им в тех случаях, когда он действительно необходим.
Поэтому я уточнил в коменте goto LABEL.
Необходимость использования конструкции "goto LABEL" практически никогда себя не оправдывает (в профессиональном девелопменте я такого точно не встречал).
Гото нужен только в обном зяыке: в ассемблере.
В остальных языках он не нужен. Это открыл Дейкстра в 70х.
Взрослые программисты обычно знают что нехорошо использовать гоуту, глобальные переменные и прочие ужасы
а вот строго ли его запрещать или просто не рекомендовать.... хм
Да и здесь гоуту применено по типу "try" и "catch", а если "try" и "catch" считать нормальным, то и это нормально.
p.s. А сам гоуту не использую.
Гоуту даже 1 раз уже говно получится. 1 раз не пидарас :))
О каком try/catch-е идет речь, когда человек пишет goto OK?!?
Perl-программисты, если им нужна конструкция типа try/catch используют или модуль TryCatch, или более легковесный Try::Tiny.
Одно дело когда у тебя прерывается выполнение какого-то блока кода из-за непредвиденной ошибки, другое когда скрипт прерывает работу, чтобы найти лейблу и сделать в неё переход.
Теперь смотри, в try и catch ты можешь сам ошибки выкидывать с помощью команды throw, а не дожидаться, когда произойдет непредвиденная ошибка.
А теперь внимание!:
Я скачал исходники перла, питона и пхп.
Я погрепал файлы с расширением ".c" на наличие оператора goto:
grep 'goto' `find . -name "*.c"` | wc -l
Итак
в Perl`е 1309 гоуту,
в Python - 3166 гоуту
в PHP - 16749 гоуту.
=====
Так же в википедии написано, что при написании Драйверов, часто юзают goto, потому что у те, кто пишет драйвера, обычно вынуждены использовать только Си, в котором нет try и catch.
В драйверах иерархический код, где ошибка может случиться на любом месте иерархии, то тут, блин, проще юзать гоуту, чем городить кучу флагов.
===
А сам я такого мнения: если можешь написать без гоуту, пиши без него.
Если не можешь написать без гоуту, всё равно пиши без него.
Если уж совсем не можешь, то пиши, то пиши с гоуту, но только выпрыгивай из всяких вложенных условий только, и прыгай вперёд, а не назад. ОЧЕНЬ ОСТОРОЖНО в общем надо применять гоуту.
во-первых, запутывает код;
во-вторых, не является стандартом у perl-разработчиков (более того это считается очень плохой манерой!),
в-третьих, не существует ситуации, при которой в perl не нашлось бы более адекватного решения (в данном случаи тут можно было заменить goto ERROR и goto OK на return _error( $res ) и return _ok( $res ), где:
sub _error { rollbackTransaction() shift; }
sub _ok { commitTransaction(); shift; }
)
По поводу try и catch.
В данном конкретном примере goto не используется как try/catch по причине того, что:
1) есть конструкция типа "goto OK;" и это не аналог throw.
2) нет передачи ошибки исключения.
3) в случаи возникновения действительно непредвиденной ситуации, данный код просто "задается" и скрипт завершит свою работу, то есть не произойдет перехвата исключения.
Еще раз напомню о том что я имею ввиду perl, возможно в С другая ситуация.
Прошу извинить меня.
http://www.youtube.com/watch?v=czoS3DT7Wno
Может автор статьи сам их пишет? )
3163
[perl-5.12.2]# grep -P '\sgoto\s' `find . -name "*.c"` | wc -l
1275
[php-5.3.3]# grep -P '\sgoto\s' `find . -name "*.c"` | wc -l
16274
Из perldoc:
про goto LABEL
The author of Perl has never felt the need to use this form of goto (in Perl, that is; C is another matter). (The difference is that C does not offer named loops combined with loop control. Perl does, and this replaces most structured uses of goto in other languages.)