Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Refactoring old modules to use roles

by Anonymous Monk
on Aug 13, 2015 at 19:47 UTC ( #1138488=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Greetings monks,

Is there any way to reuse roles in packages that are not object-oriented?

I'm working with a large, old web application codebase and trying to integrate it with modern Moo-based (Dancer2) code. I'm having some issues with a particular package, Utility.pm, in the old code; it stores some important variables (the CGI, session, database handles), and is used by just about every other module as it contains everything from file system manipulation to CGI parameter access to print formatting to making cups of tea for the programmer (OK, not yet...). I would like to refactor some of the functionality, and ideally reuse some of the roles from Moo code -- e.g. session and cookie handling, query parameter access, etc. I don't know if this would be possible, given that Utility.pm is written as a set of functions with a few package variables, rather than as an object.

Here is an overview of the code that I'm working with. MyApp does various set up tasks, finds the appropriate module to load based on http params, then loads and runs the code:

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

ConsumingModule.pm uses Utility.pm, which looks like this:

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 client +s, and # other functionality that I have roles for)

Utility.pm exports all its functions by default, and modules that use it look like this:

package ConsumingModule; ... use Utility; sub run { ... my $query = param('query'); # get a CGI parameter ... set_session_param('foo', 'bar'); # interact with the session }

As I understand it, roles can only be applied to objects or classes; I'm wondering if there is any way that I can refactor the existing Utility.pm code to enable me to use roles. There are 100+ modules that rely on Utility.pm and no test suite, so changing its API is going to be tricky at best and suicidal at worst. ;-)

Thank you!

Replies are listed 'Best First'.
Re: Refactoring old modules to use roles
by Jenda (Abbot) on Aug 14, 2015 at 09:45 UTC

    What about implementing those things as separate modules (as OO as you like) and turn Utility.pm into a thin wrapper? You may eventually gradually modify other modules and programs to use the new modules directly, but for the time being, the Utility.pm will shield the rest of the system from the changes.

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.

Re: Refactoring old modules to use roles
by (anonymized user) (Curate) on Aug 14, 2015 at 10:10 UTC
    You could extend Utility.pm into a Mooing subclass, e.g.:
    package Mootility; use Moo; use strictures 2; extends Utility; has session_param => { is => 'rw', isa => sub { return ($#_ >= 1) ? $self->set_session_param(@_) : $self->get_session_param(@_); } } # etc.

    One world, one people

    A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1138488]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (3)
As of 2019-08-21 23:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?