Единственный разумный способ откатить несколько уровней вверх по стеку вызовов - это сгенерировать исключение / смерть.
Тем не менее, вы действительно должны пересмотреть то, что вы хотите сделать. Программист (включая вас самих, через шесть месяцев) будет ожидать, что, когда вызов функции завершится, оператор после него выполнится (если не будет сгенерировано исключение). Нарушение этого ожидания приведет к ошибкам, вызванным в handle_error
, но, по-видимому, с кодом, который называется handle_error
, что делает их чрезвычайно трудными для отладки. Это нехорошо.
Вы также исходите из предположения, что абсолютно не существует ситуации , в которой будет целесообразно продолжить после обработки ошибки. Жесткое кодирование такого предположения практически является гарантией того, что, как только вы успеете забыть это, вы столкнетесь с ситуацией, когда вам нужно продолжить после вызова handle_error
(а затем потратить огромное количество времени на попытки выяснить, почему код после handle_error
не запускается).
И затем есть предположение, что вы всегда захотите пропустить точно два уровня в стеке вызовов. Это еще одно предположение, которое потерпит неудачу, как только оно будет жестко закодировано. Не только будут случаи, когда вызывающий код должен продолжаться, но также будут случаи, когда вам нужно подняться на три уровня вверх по стеку вызовов.
Так что просто выйдите из handle_error
, вызвав die
вместо return
, и перехватите исключение на соответствующем уровне, где выполнение должно продолжаться. Вы не знаете каждого места, где когда-либо будет вызываться саб, поэтому вы не можете предсказать, сколько уровней нужно будет пройти назад.
В указанном коде, если вам мешает дополнительная строка, скажем return
, вы можете использовать return $x->handle_error;
Вы даже можете избавиться от ограждающей области и сделать ее return $x->handle_error if $x->{size} > 1000;
Там - три строки удалены чем один, плюс пара скобок и две пары скобок в качестве бесплатного бонуса.
Наконец, я бы также предложил изменить имя handle_error
, чтобы лучше отразить то, что он на самом деле делает. (report_error
, может быть?) «Обработка ошибки» обычно означает очистку, чтобы устранить ошибку и продолжить выполнение. Если вы хотите, чтобы ваш handle_error
препятствовал продолжению кода, вызвавшего его, то очень маловероятно, что он очищает вещи, чтобы сделать возможным продолжение, и, опять же, это вызовет неприятные, трудно отлаживаемые сюрпризы для будущих программистов. используя этот код.