sub log_it
{
state $fh = do { open my $x, '>>', 'mylog.txt'; $x };
my $message = shift;
my $timestamp = time;
print $fh $timestamp . ": " . $message . "\n";
}
The above opens the file handle inside the sub. But because it uses a state variable, it keeps the filehandle open between calls.
One object oriented way would be something like this:
{
package Logger;
use Any::Mo;
has handle => (is => 'ro');
sub log_it {
my ($self, $message) = @_;
my $timestamp = time;
print {$self->handle}
$timestamp . ": " . $message . "\n";
}
}
my $logger = Logger->new(handle => $fh);
$logger->log_it("Hello");
$logger->log_it("World");
A little overload magic can make things more concise...
{
package Logger;
use Any::Mo;
use overload '&{}' => sub {
my $self = shift;
return sub { $self->log_it(@_) };
};
has handle => (is => 'ro');
sub log_it {
my ($self, $message) = @_;
my $timestamp = time;
print {$self->handle}
$timestamp . ": " . $message . "\n";
}
}
my $logger = Logger->new(handle => $fh);
$logger->("Hello");
$logger->("World");
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'