Ниже приведен код без пакета явного для функций ведения журнала. Я переименовал LogFuncs :: compile в logerr: setup, чтобы быть немного более явным и не загрязнять основное пространство имен. Все в perl имеет пакет, по умолчанию это просто main . Я думаю, что код, который у вас был раньше, с пакетом для функций регистрации, на самом деле был чище, и его можно было легко разделить на отдельный модуль, чтобы его было легче использовать повторно.
Что касается непонимания того, как работает код, я не уверен, как решить эту проблему, но только потому, что вы не определили какие-либо особенности того, что вы не поняли. Я предполагаю, что вы имели в виду пакеты. Пакеты Perl можно рассматривать как пространства имен или классы. В случае пакета LogFuncs вы используете его в качестве пространства имен, и созданные в нем подпрограммы доступны как методы статического класса (чтобы использовать некоторые обозначения из других более традиционных языков OO, которые могут пролить свет на это ). Пакеты FooObj и BarObj более традиционно используются в качестве объектов, предоставляя конструктор new () и ожидая, что подпрограммы внутри них будут вызываться с использованием нотации объекта (-> sub), автоматически передавая сам объект в качестве первого параметра на саб / метод. Единственное, что определяет подпрограмму как метод статического класса или метод объекта, это ожидает ли он получения объекта в качестве первого параметра. Таким образом, небольшое продуманное и тщательное программирование может создать подпрограммы, которые работают для обоих, правильно определив, что является первым переданным параметром, и действуя соответствующим образом.
#! /usr/bin/perl -w
use strict;
use Getopt::Long;
use threads;
use Time::HiRes qw( gettimeofday );
# provide tcpdump style time stamp
sub _gf_time {
my ( $seconds, $microseconds ) = gettimeofday();
my @time = localtime($seconds);
return sprintf( "%02d:%02d:%02d.%06ld",
$time[2], $time[1], $time[0], $microseconds );
}
sub logerr;
sub logerr_setup {
my %params = @_;
*logerr = $params{do_logging}
? sub {
my $msg = shift;
warn _gf_time() . " Thread " . threads->tid() . ": $msg\n";
}
: sub { };
}
{
package FooObj;
sub new {
my $class = shift;
bless {}, $class;
};
sub foo_work {
my $self = shift;
# do some foo work
main::logerr($self);
}
}
{
package BarObj;
sub new {
my $class = shift;
my $data = { fooObj => FooObj->new() };
bless $data, $class;
}
sub bar_work {
my $self = shift;
$self->{fooObj}->foo_work();
main::logerr($self);
}
}
my $do_logging = 0;
GetOptions(
"do_logging" => \$do_logging,
);
logerr_setup(do_logging => $do_logging);
my $bar = BarObj->new();
logerr("Created $bar");
$bar->bar_work();