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!


In reply to Refactoring old modules to use roles by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.