Perl 包和模块
包(Package)
基本包
perl
package MyUtils;
use strict;
use warnings;
sub add {
my ($a, $b) = @_;
return $a + $b;
}
sub multiply {
my ($a, $b) = @_;
return $a * $b;
}
1; # 包必须返回真值
# 使用
package main;
use MyUtils;
print MyUtils::add(10, 20) . "\n"; # 30
print MyUtils::multiply(5, 3) . "\n"; # 15导出符号
perl
package MyUtils;
use strict;
use warnings;
use Exporter qw(import);
our @EXPORT = qw(add subtract); # 默认导出
our @EXPORT_OK = qw(multiply divide); # 可选导出
sub add {
my ($a, $b) = @_;
return $a + $b;
}
sub subtract {
my ($a, $b) = @_;
return $a - $b;
}
sub multiply {
my ($a, $b) = @_;
return $a * $b;
}
sub divide {
my ($a, $b) = @_;
return $a / $b;
}
1;
# 使用
package main;
use MyUtils; # 导出 add 和 subtract
use MyUtils qw(multiply); # 导出 multiply
print add(10, 20) . "\n";
print multiply(5, 3) . "\n";
print MyUtils::divide(10, 2) . "\n";模块(Module)
模块结构
模块是存储在 .pm 文件中的包:
MyModule/
├── MyModule.pm
└── lib/
└── SubModule.pm创建模块
perl
# MyMath.pm
package MyMath;
use strict;
use warnings;
our $VERSION = '1.00';
sub sum {
my @numbers = @_;
my $total = 0;
$total += $_ for @numbers;
return $total;
}
sub average {
my @numbers = @_;
return sum(@numbers) / @numbers;
}
1;
# 使用
use MyMath;
my @nums = (1, 2, 3, 4, 5);
print MyMath::sum(@nums) . "\n";
print MyMath::average(@nums) . "\n";CPAN 模块
安装 CPAN 模块
bash
# 使用 cpanm(推荐)
cpanm Module::Name
# 使用 cpan
perl -MCPAN -e 'install Module::Name'
# 使用 CPANminus
cpanminus Module::Name常用 CPAN 模块
perl
# JSON 处理
use JSON;
my $data = { name => "Alice", age => 25 };
my $json = encode_json($data);
print $json . "\n";
# 数据库
use DBI;
my $dbh = DBI->connect("DBI:mysql:database=test", "user", "pass");
# HTTP 请求
use LWP::UserAgent;
my $ua = LWP::UserAgent->new();
my $response = $ua->get("http://example.com");
# 日期时间
use DateTime;
my $dt = DateTime->now();
print $dt->ymd() . "\n";模块管理工具
cpanm
bash
# 安装模块
cpanm JSON::XS
# 安装特定版本
cpanm JSON::XS@4.0
# 列出已安装的模块
cpanm -l
# 卸载模块
cpanm --uninstall JSON::XScpan
bash
# 启动 CPAN shell
perl -MCPAN -e shell
# 在 CPAN shell 中
install JSON::XS
upgrade all命名空间
包命名约定
perl
# 好的命名
package MyApp::User;
package MyApp::Database::Connection;
package MyApp::Utils::String;
# 避免的命名
package User; # 太通用
package db; # 太短使用命名空间
perl
package MyApp::User;
sub new {
my $class = shift;
bless { name => shift }, $class;
}
package main;
use MyApp::User;
my $user = MyApp::User->new("Alice");版本控制
版本号
perl
package MyModule;
use strict;
use warnings;
our $VERSION = '1.00'; # 传统版本
our $VERSION = v1.2.3; # v-string 版本
# 使用 VERSION 宏
use version; our $VERSION = qv('1.2.3');
1;
# 使用版本
use MyModule 1.00;
use MyModule v1.2.3;版本检查
perl
package MyModule;
use strict;
use warnings;
our $VERSION = '1.00';
sub import {
my ($class, $version) = @_;
if (defined $version && $version > $VERSION) {
die "Need MyModule version $version, have $VERSION\n";
}
}
1;文档
POD(Plain Old Documentation)
perl
package MyModule;
use strict;
use warnings;
our $VERSION = '1.00';
=head1 NAME
MyModule - A sample module for demonstration
=head1 SYNOPSIS
use MyModule;
my $result = MyModule::add(10, 20);
print "$result\n";
=head1 DESCRIPTION
This module provides basic mathematical operations.
=head1 FUNCTIONS
=head2 add($a, $b)
Adds two numbers and returns the result.
=cut
sub add {
my ($a, $b) = @_;
return $a + $b;
}
=head1 AUTHOR
Your Name <you@example.com>
=head1 LICENSE
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut
1;生成文档
bash
# 转换为文本
perldoc MyModule.pm
# 转换为 HTML
pod2html MyModule.pm > MyModule.html
# 转换为手册页
pod2man MyModule.pm > MyModule.1实践示例
示例 1:配置模块
perl
# MyApp/Config.pm
package MyApp::Config;
use strict;
use warnings;
use Exporter qw(import);
our @EXPORT = qw(get_config set_config);
my %config = (
database => {
host => "localhost",
port => 5432,
name => "mydb"
},
debug => 1,
log_level => "INFO"
);
sub get_config {
my ($key) = @_;
if (wantarray) {
return exists $config{$key} ? @{$config{$key}} : ();
} else {
return $config{$key};
}
}
sub set_config {
my ($key, $value) = @_;
$config{$key} = $value;
}
1;
# 使用
use MyApp::Config;
my $db_config = get_config('database');
print "Host: $db_config->{host}\n";
set_config('debug', 0);
print "Debug: " . get_config('debug') . "\n";示例 2:日志模块
perl
# MyApp/Logger.pm
package MyApp::Logger;
use strict;
use warnings;
use Exporter qw(import);
use Time::HiRes qw(time);
use POSIX qw(strftime);
our @EXPORT = qw(logger log_debug log_info log_warn log_error);
my $log_level = "INFO";
my %levels = (
DEBUG => 1,
INFO => 2,
WARN => 3,
ERROR => 4
);
sub set_level {
my ($level) = @_;
$log_level = $level;
}
sub _should_log {
my ($level) = @_;
return $levels{$level} >= $levels{$log_level};
}
sub _format_message {
my ($level, $message) = @_;
my $timestamp = strftime("%Y-%m-%d %H:%M:%S", localtime);
return "[$timestamp] [$level] $message\n";
}
sub logger {
my ($level, $message) = @_;
if (_should_log($level)) {
print _format_message($level, $message);
}
}
sub log_debug { logger('DEBUG', @_); }
sub log_info { logger('INFO', @_); }
sub log_warn { logger('WARN', @_); }
sub log_error { logger('ERROR', @_); }
1;
# 使用
use MyApp::Logger;
log_debug("This is debug message");
log_info("Application started");
log_warn("Low disk space");
log_error("Connection failed");示例 3:数据库助手模块
perl
# MyApp/DBHelper.pm
package MyApp::DBHelper;
use strict;
use warnings;
use DBI;
sub new {
my ($class, $config) = @_;
my $self = {
dbh => DBI->connect(
"DBI:mysql:database=$config->{database};host=$config->{host}",
$config->{username},
$config->{password},
{ RaiseError => 1, AutoCommit => 0 }
)
};
bless $self, $class;
return $self;
}
sub execute {
my ($self, $sql, @params) = @_;
my $sth = $self->{dbh}->prepare($sql);
$sth->execute(@params);
return $sth;
}
sub select_all {
my ($self, $sql, @params) = @_;
my $sth = $self->execute($sql, @params);
return $sth->fetchall_arrayref({});
}
sub select_one {
my ($self, $sql, @params) = @_;
return $self->{dbh}->selectrow_hashref($sql, undef, @params);
}
sub commit {
my ($self) = @_;
$self->{dbh}->commit();
}
sub rollback {
my ($self) = @_;
$self->{dbh}->rollback();
}
sub disconnect {
my ($self) = @_;
$self->{dbh}->disconnect();
}
1;
# 使用
use MyApp::DBHelper;
my $db = MyApp::DBHelper->new({
database => "test",
host => "localhost",
username => "user",
password => "pass"
});
eval {
my $users = $db->select_all("SELECT * FROM users");
foreach my $user (@$users) {
print "$user->{name}\n";
}
$db->commit();
};
if ($@) {
$db->rollback();
die "Database error: $@";
}
$db->disconnect();小结
本章节学习了 Perl 的包和模块:
- ✅ 包(Package)基础
- ✅ 模块(Module)结构
- ✅ CPAN 模块
- ✅ 模块管理工具
- ✅ 命名空间
- ✅ 版本控制
- ✅ 文档(POD)
- ✅ 实践示例
接下来,我们将学习 Perl 进程管理。