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

Fellow Monks,

I have the following subroutine contained in many cgi scripts, its used for reporting dbi errors.
sub handle_error{ my $msg = shift ||' '; my $dbh = shift ||' '; my $sth = shift ||' '; #html::template - handle_error.tmpl my $tem = HTML::Template->new(filename => "handle_error.tmpl"); $tem -> param(message => $msg); print $tem->output; #finish the state handle and disconnect, if necessary $sth->finish() if $sth; $dbh->disconnect() if $dbh; exit 0; }
Does it make sense to put this into a module?
Being a relative newbie, how would I go about doing this?

Thanks in advance,
Jonathan

Replies are listed 'Best First'.
Re: Changing a subroutine to a module
by CountZero (Bishop) on Feb 10, 2005 at 12:31 UTC
    If you use it more than once, it is a good candidate to put it in a module.

    Of course you can seldom "translate" a subroutine directly into a module as --almost by definition-- a module should be useful in more than one place and therefore you might have to include some extra parameters to customize the routine and make it more general.

    On a totally different tack: why do you want to put a space character in the variables if there is nothing passed to the subroutine? Doesn't it make the $sth->finish() if $sth; $dbh->disconnect() if $dbh; superfluous as now you will always succeed in these tests (space is considered TRUE!)?

    Another question (just being curious): why do you exit the subroutine always with a zero value (exit 0). The reason cannot be that you want to check the return value of the subroutine as it is always zero? Hence the question, why zero?

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

Re: Changing a subroutine to a module
by boboson (Monk) on Feb 10, 2005 at 13:18 UTC
    I am not going to get into any specific but if you want to make a module out of it here is one way of doing it:

    create a file with the .pm extenstion for example Error.pm
    This goes inside:

    package Error; use Exporter; @ISA = ('Exporter'); @EXPORT = ('handle_error'); sub handle_error{ my $msg = shift ||' '; my $dbh = shift ||' '; my $sth = shift ||' '; #html::template - handle_error.tmpl my $tem = HTML::Template->new(filename => "handle_error.tmpl"); $tem -> param(message => $msg); print $tem->output; #finish the state handle and disconnect, if necessary $sth->finish() if $sth; $dbh->disconnect() if $dbh; exit 0; } 1;
    in your calling script give the path to your newly created module Error.pm
    use lib ("/home/z/xxx/www/modules/"); use Error;
    Now you can use your subroutine. Your subroutine probably won't work now, but hopefully you get the picture.
Re: Changing a subroutine to a module
by cog (Parson) on Feb 10, 2005 at 10:37 UTC
    If you're using it in "many cgi scripts", yes, it does make sense putting it into a module; this way you'll prevent yourself from writing it over and over again.

    As a plus, whenever you feel like changing your code, you'll only have to do it *once*, in the module.

    How to do it... well, there's a lot to be said on the subject (I wrote a full article on this, but it hasn't been published yet). Use Module::Starter to start a module easily, check out the files it creates and post your questions here as they arise.

Re: Changing a subroutine to a module
by weedom (Acolyte) on Feb 10, 2005 at 11:00 UTC

    It makes absolute sense to use it in a module. I'd also suggest changing the name, of the subroutine slightly, though. Perhaps call it handle_db_error. then you can have other routines such as handle_io_error, or somesuch.

    Now read chapter 11 of the Bible. There are too many options to really specify how to do this in a single post. Are you going OO, for example? Do you want to have the routine available in all scripts, or should it be imported explicitly?

Re: Changing a subroutine to a module
by hok_si_la (Curate) on Feb 10, 2005 at 15:00 UTC
    Jonathan,

    With regard to building a module, these links helped me, also a newbie, a ton.

    http://builder.com.com/5100-6371-1044686-2.html#Listing%20B
    http://mathforum.org/~ken/perl_modules.html

    Good luck,
    hok_si_la
Re: Changing a subroutine to a module
by ikegami (Patriarch) on Feb 10, 2005 at 18:08 UTC

    The following is wrong since ' ' is true:

    my $dbh = shift ||' '; my $sth = shift ||' '; ... $sth->finish() if $sth; $dbh->disconnect() if $dbh;

    The above is equivalent to:

    my $dbh = shift; my $sth = shift; ... if ($sth) { $sth->finish(); } else { ' '->finish(); # RUNTIME ERROR } if ($sth) { $dbh->disconnect(); } else { ' '->diconnect(); # RUNTIME ERROR }

    Why not just do this:

    my $dbh = shift; my $sth = shift; ... $sth->finish() if $sth; $dbh->disconnect() if $dbh;
Re: Changing a subroutine to a module
by cbrandtbuffalo (Deacon) on Feb 10, 2005 at 18:39 UTC
    If you're not sure about the specifics of creating a module, an intermediate step is to put it in a 'library.' This just means you stick the sub into a separate file and put a 1; at the end of the file. Then, in all of your programs, add a 'require' statement and point to the library file. Then the sub will be available to the program. This is one step away from creating an actual module, but it removes the package and Exporter issues. There is an example here.

    When you convert it to a shared sub, you may want to consider using named parameters when you pass in variables. This makes it much easier to change things in the future without breaking a bunch of code that is relying on the position of passed in variables.

    There is a good section on named parameters in Effective Perl Programming. Basically, you pass a hash into the sub rather than an array and pull the parameters off as a hash.

Re: Changing a subroutine to a module
by TomDLux (Vicar) on Feb 10, 2005 at 19:51 UTC

    I would suggest that you don't want to tell the user too much about your error.

    The ordinary user only cares whether you can answer his query or not, but the malicious user might use debugging info to find ways to break into your system.

    What you DO need is to make sure messages get into the apache log.

    --
    TTTATCGGTCGTTATATAGATGTTTGCA