$config = { verbosity => 3, logger => new Logger(), ... # hundreds of configuration settings }; #### $params = { from => ..., to => ..., # override the timeout of the system-wide config timeout => ..., # this is the config read from file config => { verbosity => 3, logger => ..., timeout => 5, ... } }; sub distance { my $params = shift; # the timeout value will be the config's unless # caller passed their own value to temporarily override it my $timeout = exists($params->{timeout}) ? $params->{timeout} : $params->{config}->{timeout} ; ... # similarly, I return back multiple values in a hash(ref) return { errormsg => 'nothing', status => 1, # all OK! distance => 42 }; } # call it my $ret = distance($params); die $ret->{errormsg} unless $ret->{status} == 1; #### # I am skipping some boilerplate package Calc; sub new { my ($configfile, ...) = @_; my $config = read_configfile($configfile); my $internal_data = { config => $config, stash => {} }; # bless etc. } sub distance { my ($internal_data, $params) = @_; # internal_data holds config, # $params holds from, to and anything to override # config just for the life of this call ... # optionally save results to the stash $internal_data->{stash}->{distance} = 42; # return something back return { errormsg => 'nothing', status => 1, # correct distance => 42 }; } #### my $calcobj = Calc->new('settings.config'); my $res = $calcobj->distance({ from => ..., to => ..., # optionally temporarily # override system-wide config setting timeout => ..., });