package Foo; my $dbh; sub init_foo { my( %script_config )= @_; # Read config file ... # Connect to database $dbh ||= $config{ dbh } || connect_to_foo_database( %script_config ); # Set up cache ... }; #### sub frobnicate { my( $self, %options )= @_; $options{ dbh } ||= $self->get_dbh; ... }; sub get_dbh { my( $self )= @_; $self->{ dbh } ||= do { DBI->connect( $self->{dbi_parameters} ); }; }; #### package Module::MagicInit; use strict; my @init_queue; sub register_init { push @init_queue, [ (caller(1))[2], @_ ]; }; sub init { for my $task (@init_queue) { my( $package, $callback, @args )= @$task; $callback->( @args ) or die "Init failed for $package."; }; }; #### package Foo; use Module::MagicInit; register_init( \&my_init, 'Hello', 'World' ); sub my_init { my( $greeting, $name )= @_; print "$greeting, $name\n"; }; 1; #### #!perl -w use strict; use Module::MagicInit; ... Module::MagicInit::init();