in reply to Re: CGI::Application, Templates, and CSS
in thread CGI::Application, Templates, and CSS

Hi, I discovered CGI::Application a couple of weeks ago, and was shocked at how well structured it made my applications. Unfortunatley as they've grown, i've encountered what you mention in your post, lots of runmodes, and most of them call each other as an easy way of handling error conditions.

sub show_monkey { my $self = shift; my $db = $self->param('db'); my $q = $self->query(); my $monkey_id = $q->param('monkey_id'); my $ref = $db->select_monkey($monkey_id); unless ( defined($ref) ) { $self->param('error' , "Invalid Monkey ID: $monkey_id in show_monk +ey()"); return $self->show_all_monkies(); } my $tmpl = $self->load_tmpl('show_monkey.tmpl'); $tmpl->param( $ref ); return $tmpl->output(); }
To try and simplify things, I moved all of my database calls into a seperate object that was initialised with my main CGI::Application and set as the db param. This simplified the main portion of my code, but there is still a great deal of runmodes all calling each other.

Do you have any tips on how best to structure the runmodes? I seem to have a lot of add_blah1 , edit_blah1 , delete_blah1 runmodes, is there a better way to handle that?

Also while i'm asking questions. I have a couple of CGI::Application objects now, one say Monkey::Gallery and another Monkey::News is there a tidy way to call one of the runmodes of Monkey::News (recent_news) for example that can be passed as a param into my main Monkey::Gallery page?

Anyway, any advice anyone can give me would be greatly appreciated. I've been using perl for years now, but have only really started writing stuff on a scale to start worrying about how tidy and modular it is. (I'm reading Design Patterns so i'm on the ladder).
Many Thanks,

Steve

Replies are listed 'Best First'.
Re: Re: Re: CGI::Application, Templates, and CSS
by Ryszard (Priest) on Feb 02, 2002 at 01:52 UTC
    I guess the best advice i can give you is, if you do it more than once, make a seperate subby (or method).

    For my web apps, i've extracted all my db calls into two subroutines, one for selecting and one for updating.

    Do a concept model of your apps, and put all the concepts you've found into discrete buckets.

    Do you have any tips on how best to structure the runmodes? I seem to have a lot of add_blah1 , edit_blah1 , delete_blah1 runmodes, is there a better way to handle that?

    If that there are several methods to a concept, perhaps you could create a 'super routine' that you pass flags to inorder to perform the varous functions.

    For example if you have 3 methods add, edit, delete, you could make a routine that you pass the flags to {method=>'add'} and your routine would get the approprate sql, do the varous functions et al.

    This thing is kind of contentious (and subjective) as it is combining several different methods in one function, which would normall be split into the 'high-cohesion, low coupling' style.

    If you build the underlying infrastructure (ie dbi calls, content aggregation et al), and parameterise is accordingly (ie build your routines in a very generic manner) you can build the business logic for the (add, update, delete) functions in one routine that would farm out the physical operations to you prebuilt infrastructure and return $output.

    As I mentioned your style to abstraction is subjective, and before putting fingers to keyboard I would suggest having a good long think about your logic, with a view to code reuse, even going so far as to sketch it out on paper.

    The approach i use is a three tier approach:
    1st tier: the application or user input level
    2nd tier: the signal box level. The input from the user is interpreted, and calls are made to the bottom layer.
    3rd tier: The layer that goes and actually *does* things. ie i'll make my dbi calls, do my content aggregation etc.

    I code in this manner, and it works for me.

    So in your example you could do something like:

    rm=mode1&method=add; rm=mode1&method=edit; rm=mode1&method=delete

    Of course everything has extremes, and if you have 20 methods for a concept, perhaps this is not the best method to persue.

    Update: I've just noticed youre not untainting your $q->param() variables before reassigning them. I dont know what the rest of your code looks like, so you may have done it elsewhere. If not, you must untaint all externally assigned variables before using them if you want to build a secure web applicaiton. This inclues both sides of your app, ie the user input end and the database/os end.