in reply to My first stab at OO perl...

*laughs* ref($cargocult) || $cargocult; Very nice! :-)

Otherwise, it all looks fine. You've got a lot of the idioms I would use in an OO situation.

A few ideas to bring (and boggle) you further:

  1. Use closures to generate the accessors in Expense.
    sub new { # Stuff up here foreach my $attrib (keys %$self) { my $conv_attrib = $attrib; $conv_attrib =~ s/^_(\w+)$/lc $1/e; no strict 'refs'; *{__PACKAGE__ . "::$conv_attrib"} = gen_closure($attrib); } return $self; } sub gen_closure { my $attrib = shift; return sub { my $self = shift; if (@_) { $self->{$attrib} = shift; } return $self->{$attrib}; } }
    That is much easier to maintain when you start hitting 20 or 30 attributes in your objects.
  2. Look at separating your database logic from your business logic. This is something we're hitting where I work right now. It'll sound crazy, but if this is going to scale, you will need to do that. Maybe something along the lines of DB::Expense so that if your database schema changes (which it will), you aren't left scrambling to fix your beautiful OO structures.

Good luck!

------
We are the carpenters and bricklayers of the Information Age.

Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Replies are listed 'Best First'.
Re: Re: My first stab at OO perl...
by mp (Deacon) on Jul 16, 2002 at 16:57 UTC
    You could conserve resources by generating constructors at "compile" time rather than every time the constructor (new) is called. Class::MethodMaker could do this for you:
    use Class::MethodMaker get_set => [ qw( accessor1 accessor2 ) ];
    Or you could update 'new' above to check to see if the accessor exists before re-building it.
      Fine. Change the = to ||= and it's ok.

      ------
      We are the carpenters and bricklayers of the Information Age.

      Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Re: Re: My first stab at OO perl...
by Theseus (Pilgrim) on Jul 16, 2002 at 16:00 UTC
    Damn, that closure code threw me for a loop at first. It took two or three times before I fully understood what was going on. I haven't really had the need or desire to play with typeglobs and creating subroutines on the fly, but maybe I need to take a look at it, seems like it could save me some work if I learn a few tricks...