Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
I've never been a huge advocate of OO; I use objects when it's convenient. However, the more code I write, the more I begin to realise that I should be using objects a lot more. A recent solution to a problem I had re-enforced this for me. Although this is probably pretty obvious to a lot of Monks, I thought I'd share my story with you, in case someone finds it useful.

The Problem

I've got a mod_perl application that uses HTML::Template throughout. At the time I wrote it, there wasn't any off-the-shelf framework that I really liked (I'd probably use Catalyst now), and since it was a fairly simple app, I rolled my own.

This just consisted of a Handler that created my own Request object, and passed this to every 'crontroller' function. It included an Apache::Session object, database connection, etc.

The problem was, I needed to add an item to the main menu (displayed on every page) for administrator users only. Previously, there hadn't even been an administrator user, but I did have a 'top.html' template, included by every other template with the menu.

I wrote some code to read the administrator flag from the DB, and store it in the session - nothing tricky there.

Wrapping HTML::Template

I didn't like the thought of passing an adminstrator flag every time I made a call to HTML::Template's param(), so I obviously needed to wrap it.

Luckily, HTML::Template is OO, so all I needed to do was sub-class it. This was pretty straight forward:
package MyApp::HTML::Template; use base qw(HTML::Template); sub new { my $class = shift; my %params = @_; return $class->SUPER::new( %params, die_on_bad_params => 0, ); }
At the same time, I figured I'd default that pesky die_on_bad_params to off, since I hardly ever use it.

Then all I had to do was change every call to HTML::Template->new() to MyApp::HTML::Template->new() - a simple find & replace.

Passing the Flag

Ok, so I had a wrapper for every call to HTML::Template, but now I needed the flag to be passed in to each template. Again, I didn't want to do this every time I called param(), so I obviously needed to override it.

sub param { my $self = shift; my %params = @_; $self->SUPER::param(%params); }

Great, but now I had a problem. The Request object wasn't accessable from my wrapper class - it's out of scope of course. And I didn't want to pass *that* in every time.

After a bit of thinking, I realised I just needed to make my Request class a singleton. This was as simple as inheriting from Apache::Singleton (this module was necessary rather than Class::Singleton, so that the singleton is destroyed at the end of the mod_perl request).

Then, from the param method, I can simply call MyApp::Request->instance() and I'll have the request object with the flag I need, which can then be passed to param().

Conclusion

I've often been suspicious of the 'use objects unless you have a really good reason not to' attitude, but as I learn more, I find that even if there doesn't seem to be a really good reason to use OO at the time you write something, when it comes to maintenance, OO can often make your life a lot easier.

Update: Fixed a spelling error
Update 2: Updated constructor, as per jeffa's suggestion.

In reply to The Power of Objects by Mutant

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!
  • 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, 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, 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.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others rifling through the Monastery: (5)
    As of 2015-07-04 10:29 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









      Results (59 votes), past polls