--- Guard/Guard.pm 2008/12/13 17:50:29 1.3 +++ Guard/Guard.pm 2008/12/13 18:34:18 1.4 @@ -6,6 +6,15 @@ use Guard; + # temporarily chdir to "/etc" directory, but make sure + # to go back to "/" no matter how myfun exits: + sub dosomething { + scope_guard { chdir "/" }; + chdir "/etc"; + + call_function_that_might_die_or_other_fun_stuff; + } + =head1 DESCRIPTION This module implements so-called "guards". A guard is something (usually @@ -62,17 +71,29 @@ Except it is much faster, and the whole thing gets executed even when the BLOCK calls C, C, C or escapes via other means. +If multiple BLOCKs are registered to the same scope, they will be executed +in reverse order. Stuff like C is managed via the same mechanism, +so variables Cised after calling C will be restored +when the guard runs. + See B, below, for an explanation of exception handling (C) within guard blocks. -Example: Temporarily change the directory to F and make sure it's -set back to F when the function returns: +Example: temporarily change the timezone for the current process, +ensuring it will be reset when the C scope is exited: + + use Guard; + use POSIX (); + + if ($need_to_switch_tz) { + # make sure we call tzset after $ENV{TZ} has been restored + scope_guard { POSIX::tzset }; - sub dosomething { - scope_guard { chdir "/" }; - chdir "/etc"; + # localise after the scope_guard, so it gets undone in time + local $ENV{TZ} = "Europe/London"; + POSIX::tzset; - ... + # do something with the new timezone } =item my $guard = guard BLOCK