package MyApp; # modern Moo-based app use Moo; # run initialisation checks # set up session, parse http params # run routing code: load (legacy) module, run the code load 'ConsumingModule'; # this module uses Utility.pm ConsumingModule::run(); # render output #### package Utility; ... my ($cgi, $session, $dbh, $config, ...); # create (but don't set) # important variables # do miscellaneous stuff ... init(); ... sub init { $cgi = CGI->new(); $session = CGI::Session->new( $params ); ... } # later on sub get_session_param { my $p = shift; return $session->param( $p ); } sub set_session_param { my ($p, $val) = @_; $session->param( $p, $val ); } # plus other stuff for interacting with $session sub param { my $p = shift; return $cgi->param( $p ); } # plus other cgi interactions # 9950 lines of other code # (including similar code for setting up database handles, http clients, and # other functionality that I have roles for) #### package ConsumingModule; ... use Utility; sub run { ... my $query = param('query'); # get a CGI parameter ... set_session_param('foo', 'bar'); # interact with the session }