オブジェクト指向を勉強してみる3

package Log;

# Thank you for
# - http://search.cpan.org/~gng/File-Log-1.05/Log.pm
# - http://perldoc.jp/docs/modules/File-Log-1.02/Log.pod
# - http://www.jp-z.jp/perlmemo/file_FindBin.html
# - File::Temp

use strict;
use warnings;
use File::Basename;
use File::Path;
use Fcntl;
use FindBin qw($Bin $Script);

sub new
{
	my $class = shift;
	
	# logfile
	(my $def_logfile = "$Bin/$Script") =~ s/\.\S+$/\.log/;

	my %opt = (
		'logfile'   => $def_logfile,
		'logsize'   => 0,
		'rotate'    => 0,
		'debug'     => 0,
		'pid'       => "no",
	);
	%opt = (%opt, @_) if @_;
	
	my $self = \%opt;
	bless $self, $class;
	return $self;
}

sub log_out
{
	my $self = shift;
	my $logfile = $self->{logfile};
	my $logsize = $self->{logsize};
	my $rotate  = $self->{rotate};

	my ($msg) = @_;
    
	# --- setting ---
	#my $logfile = "/tmp/log/hato/hato.log";
	#my $rotate  = 9;
	#my $logsize = 512 * 1024;
	# ---------------

	my $dirname = dirname $logfile;
	eval { mkpath($dirname, 0, 0755) } unless -d $dirname;
    
	sysopen my $fh, $logfile, O_WRONLY|O_CREAT|O_APPEND or 
	           die "$!:$logfile wasn't written";
	flock($fh, 2);
	my $line = sprintf("%s $msg", get_time());
	print $fh "$line\n";
	close($fh);
	
	if ($logsize != 0 and $rotate != 0) {
		rotate_file(
			logfile => $logfile,
			logsize => $logsize,
			rotate  => $rotate,
		);
	}
	
	return $line;
}

sub rotate_file
{
	my (%hash) = @_;
	my $logfile = $hash{logfile};
	my $logsize = $hash{logsize};
	my $rotate  = $hash{rotate};

	if (defined $rotate) {
		my $size = -s $logfile;
    
		if ($size >= $logsize) {
			foreach my $i (1..$rotate) {
				my $after  = $rotate - $i + 1;
				my $before = $rotate - $i;
				my $a_logfile = "$logfile.$after";
				my $b_logfile = ($before) ? "$logfile.$before" : $logfile;
				
				if (-f $b_logfile) {
					rename($b_logfile, $a_logfile);
				}
			}
		}
	}
	return ;
}


sub get_time
{
	#     0    1    2     3     4    5     6     7     8
	my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
	my @abbr = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
	
	# messages style
	return sprintf("%s %02d %02d:%02d:%02d", $abbr[$mon], $mday, $hour, $min, $sec);
}

package main;

use strict;
use warnings;
use Data::Dumper;

#print Log::log_out("test") . "\n";
my $a = Log->new( 
	logfile => "/tmp/a.log",
	logsize => 100,
	rotate  => 3,
);

$a->log_out("test");
print Dumper($a);