CN Perl Advent Calendar 2009-12-03

End Scope

by Fayland Lam

CPAN 上有很多支持在 scope 结束后运行某些代码,其中最常用的是 Scope::GuardB::Hooks::EndOfScope

Scope::Guard 采用最常见的 DESTROY 方法。Scope::Guard 可以通过 dismiss 来取消。

   1 use Net::FTP;
   2 use Scope::Guard;
   3 
   4 {
   5     my $err;
   6     my $sg = Scope::Guard->new(
   7         sub { email_error($err); die $err; }
   8     );
   9     my $ftp = Net::FTP->new($host, Debug => 0)
  10       or do { return $err = "Cannot connect to $host: $@"; };
  11     $ftp->login($user, $pass)
  12       or do { return $err = "Cannot login " . $ftp->message; };
  13 
  14     $sg->dismiss();
  15 }

B::Hooks::EndOfScope 使用 Variable::Magic 中的魔术 $^H. EndOfScope 的强悍之处在于支持 Moose 的方法修改,并且支持多个 on_scope_end 加载。

   1     # Make sure that the application class becomes immutable at this point,
   2     # which ensures that it gets an inlined constructor. This means that it
   3     # works even if the user has added a plugin which contains a new method.
   4     # Note however that we have to do the work on scope end, so that method
   5     # modifiers work correctly in MyApp (as you have to call setup _before_
   6     # applying modifiers).
   7     B::Hooks::EndOfScope::on_scope_end {
   8         return if $@;
   9         my $meta = Class::MOP::get_metaclass_by_name($class);
  10         if ( $meta->is_immutable && ! { $meta->immutable_options }->{inline_constructor} ) {
  11             warn "You made your application class ($class) immutable, "
  12                 . "but did not inline the constructor.\n"
  13                 . "This will break catalyst, please pass "
  14                 . "(replace_constructor => 1) when making your class immutable.\n";
  15         }
  16         $meta->make_immutable(replace_constructor => 1) unless $meta->is_immutable;
  17     };
  18 
  19     $class->setup_finalize;

上述代码来自 Catalyst

我们一般在多处 return, next 或复杂子程序调用的时候,为了使代码更简洁而采用上述模块。

谢谢。

View Source (POD)