my $sub = sub { ... }; no strict 'refs'; *{"Alex::Log::$name"} = $sub; #### sub _doLog { my ($self, $lid, $pid, $msg) = @_; $msg = '[PID:$$] ' . $msg; substr($msg, 2045) = '...' if length($msg) > 2048; my $sth = $self->{dbh}->prepare("INSERT INTO Logs ( log_level_id, log_program_id, message ) VALUES ( ?, ?, ? )" ); $sth->execute( $lid, $pid, $msg ); } #### my $singleton; sub new { return $singleton if $singleton; # bypass setup if already done my $class = shift; my %args = @_; croak "No program name given to constructor. ( program => 'foo' required )" unless exists $args{program}; my $pname = $args{program}; my $dbh = Alex::DBI->new; my ( $pid ) = $dbh->selectrow_array( "SELECT id FROM Log_Programs WHERE name = '$pname'" ); croak "Program $pname not in database" unless $pid; $singleton = bless( { dbh => $dbh }, $class ); my $levels = $dbh->selectall_arrayref( "SELECT id, name FROM Log_Levels" foreach my $lev( @$levels ) { no strict 'refs'; *{'Alex::Log::' . $lev->[1]} = sub { shift->_doLog(@$lev, @_); }; } $singleton; ); #### foreach my $lev( @$levels ) { no strict 'refs'; *{'Alex::Log::' . $lev->[1]} = sub { _doLog(@$lev, @_); }; } #### sub _doLog { my ($lid, $pid, $msg) = @_; #... my $sth = _init()->{dbh}->prepare("INSERT INTO Logs ( log_level_id, log_program_id, message ) VALUES ( ?, ?, ? )" ); #... } #### our @EXPORT_OK; use base 'Exporter'; sub import { _init(); goto \&Exporter::import; } #### foreach my $lev( @$levels ) { push @EXPORT_OK, $lev->[1]; # set up the allowable exports no strict 'refs'; *{'Alex::Log::' . $lev->[1]} = sub { _doLog(@$lev, @_); }; }