CPAN 上有很多支持在 scope 结束后运行某些代码,其中最常用的是 Scope::Guard 和 B::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 或复杂子程序调用的时候,为了使代码更简洁而采用上述模块。
谢谢。