我有一个小的perl模块,我正在使用Getopt :: Long,我想我也可以使用Pod :: Usage来获得漂亮的帮助显示.
经过一番摆弄后,我得到了相当好的工作,只有一个小例外.我无法设置输出的宽度.
我的终端是191个字符宽.使用perldoc Module.pm,它正确地将文档格式化为该宽度.使用pod2usage(),它使用默认宽度76个字符.
我无法弄清楚如何将宽度选项传入格式化程序.该文档展示了如何使用BEGIN块设置不同的格式化程序(如Pod :: Text :: Termcap),并使用Term :: ReadKey来拉宽度(已验证),但我无法将格式化程序设置为看见.
任何提示?
这是我正在尝试测试的完整模块,以及一个加载它的小测试脚本.要明白我的意思,打开一个宽度合理的终端(132或更多,这很明显),并将"./test.pl --man"的输出与"perldoc MUD :: Config"的输出进行比较.
我可以没有perldoc添加的手册页样式页眉和页脚,但我希望它尊重(和使用)终端宽度.
test.pl
#!/usr/bin/perl -w
use strict;
use warnings;
use MUD::Config;
#use MUD::Logging;
my $config = new MUD::Config @ARGV;
#my $logger = new MUD::Logging $config;
#$bootlog->info("Logging initialized");
#$bootlog->info("Program exiting");
Run Code Online (Sandbox Code Playgroud)
和MUD/Config.pm
#!/usr/bin/perl -w
package MUD::Config;
=pod
=head1 NAME
MUD::Config -- Configuration options for PocketMUD
=head1 SYNOPSIS
./PocketMUD [OPTIONS]
=head1 OPTIONS
=over 8
=item B<--dbname>
Specifiy the name of the database used by PocketMUD S<(default B<pocketmud>)>.
=item B<--dbhost>
Specify the IP address used to connect to the database S<(default B<localhost>)>.
=item B<--dbport>
Specify the port number used to connect to the database S<(default B<5432>)>.
=item B<--dbuser>
Specify the username used to connect to the database S<(default B<quixadhal>)>.
=item B<--dbpass>
Specify the password used to connect to the database S<(default B<password>)>.
=item B<--dsn>
The DSN is the full connection string used to connect to the database. It includes the
values listed above, as well as several other options specific to the database used.
S<(default B<DBI:Pg:dbname=$db_name;host=$db_host;port=$db_port;sslmode=prefer;options=--autocommit=on>)>
=item B<--logfile>
Specify the text file used for debugging/logging output S<(default B</home/quixadhal/PocketMUD/debug-server.log>)>.
=item B<--port>
Specify the port used for player connections S<(default B<4444>)>.
=item B<--help>
Display usage information for PocketmUD.
=item B<--man>
Display full documentation of configuration module details.
=back
=head1 DESCRIPTION
PocketMUD is a perl re-implementation of SocketMUD.
It is meant to be a barebones MUD server, written in perl,
which can be easily modified and extended.
=head1 METHODS
=cut
use strict;
use warnings;
use Getopt::Long qw( GetOptionsFromArray );
use Config::IniFiles;
use Data::Dumper;
BEGIN {
use Term::ReadKey;
my ($width, $height, $pixel_width, $pixel_height) = GetTerminalSize();
#print "WIDTH: $width\n";
$Pod::Usage::Formatter = 'Pod::Text::Termcap';
$Pod::Usage::width = $width;
}
use Pod::Usage;
use Pod::Find qw(pod_where);
Getopt::Long::Configure('prefix_pattern=(?:--|-)?'); # Make dashes optional for arguments
=pod
B<new( @ARGV )> (constructor)
Create a new configuration class. You should only need ONE instance of this
class, under normal circumstances.
Parameters passed in are usually the command line's B<@ARGV> array. Options that
can be specified are listed in the B<OPTIONS> section, above.
Returns: configuration data object.
=cut
sub new {
my $class = shift;
my @args = @_;
my ($db_name, $db_host, $db_port, $db_user, $db_pass, $DSN);
my ($logfile, $port);
my $HOME = $ENV{HOME} || ".";
# Order matters... First we check the global config file, then the local one...
foreach my $cfgfile ( "/etc/pocketmud.ini", "$HOME/.pocketmud.ini", "./pocketmud.ini" ) {
next if !-e $cfgfile;
my $cfg = Config::IniFiles->new( -file => "$cfgfile", -handle_trailing_comment => 1, -nocase => 1, -fallback => 'GENERAL', -default => 'GENERAL' );
$db_name = $cfg->val('database', 'name') if $cfg->exists('database', 'name');
$db_host = $cfg->val('database', 'host') if $cfg->exists('database', 'host');
$db_port = $cfg->val('database', 'port') if $cfg->exists('database', 'port');
$db_user = $cfg->val('database', 'user') if $cfg->exists('database', 'user');
$db_pass = $cfg->val('database', 'password') if $cfg->exists('database', 'password');
$DSN = $cfg->val('database', 'dsn') if $cfg->exists('database', 'dsn');
$logfile = $cfg->val('general', 'logfile') if $cfg->exists('general', 'logfile');
$port = $cfg->val('general', 'port') if $cfg->exists('general', 'port');
}
# Then we check arguments from the constructor
GetOptionsFromArray( \@args ,
'dbname:s' => \$db_name,
'dbhost:s' => \$db_host,
'dbport:i' => \$db_port,
'dbuser:s' => \$db_user,
'dbpass:s' => \$db_pass,
'dsn:s' => \$DSN,
'logfile:s' => \$logfile,
'port:i' => \$port,
'help|?' => sub { pod2usage( -input => pod_where( {-inc => 1}, __PACKAGE__), -exitval => 1 ); },
'man' => sub { pod2usage( -input => pod_where( {-inc => 1}, __PACKAGE__), -exitval => 2, -verbose => 2 ); },
);
# Finally, we fall back to hard-coded defaults
$db_name = 'pocketmud' if !defined $db_name and !defined $DSN;
$db_host = 'localhost' if !defined $db_host and !defined $DSN;
$db_port = 5432 if !defined $db_port and !defined $DSN;
$db_user = 'quixadhal' if !defined $db_user;
$db_pass = 'password' if !defined $db_pass;
$logfile = '/home/quixadhal/PocketMUD/debug-server.log' if !defined $logfile;
$port = 4444 if !defined $port;
$DSN = "DBI:Pg:dbname=$db_name;host=$db_host;port=$db_port;sslmode=prefer;options=--autocommit=on" if !defined $DSN and defined $db_name and defined $db_host and defined $db_port;
die "Either a valid DSN or a valid database name, host, and port MUST exist in configuration data" if !defined $DSN;
die "A valid database username MUST exist in configuration data" if !defined $db_user;
die "A valid database password MUST exist in configuration data" if !defined $db_pass;
die "A valid logfile MUST be defined in configuration data" if !defined $logfile;
die "A valid port MUST be defined in configuration data" if !defined $port;
my $self = {
DB_NAME => $db_name,
DB_HOST => $db_host,
DB_PORT => $db_port,
DB_USER => $db_user,
DB_PASS => $db_pass,
DSN => $DSN,
LOGFILE => $logfile,
PORT => $port,
};
bless $self, $class;
print Dumper($self);
return $self;
}
sub dsn {
my $self = shift;
if ( @_ ) {
$self->{DSN} = shift;
}
return $self->{DSN};
}
sub db_user {
my $self = shift;
if ( @_ ) {
$self->{DB_USER} = shift;
}
return $self->{DB_USER};
}
sub db_pass {
my $self = shift;
if ( @_ ) {
$self->{DB_PASS} = shift;
}
return $self->{DB_PASS};
}
sub logfile {
my $self = shift;
if ( @_ ) {
$self->{LOGFILE} = shift;
}
return $self->{LOGFILE};
}
sub port {
my $self = shift;
if ( @_ ) {
$self->{PORT} = shift;
}
return $self->{PORT};
}
1;
Run Code Online (Sandbox Code Playgroud)
伙计,我真的很想在这方面寻找挑战......
我查看了代码,Pod::Usage看看发生了什么。Pod::Usage直接使用该perldoc命令,因此看起来两者都以perldoc相同pod2usage的方式打印。事实上,在我的系统上,两者perldoc都pod2usage默认或多或少为 80 列。我不知道为什么它在你的系统上有所不同。
有一个例外:
如果设置-noperldoc参数,它将用于Pod::Text格式化,并且在创建新对象时Pod::Text有一个选项。-width => $widthPod::Text
我想我也许能够传递一个未记录的 -width参数pod2usage,并且它将传递给$parser创建的对象。该对象是一个Pod::Usage对象,但是Pod::Usage是 的子类Pod::Text。
没有骰子。
这些选项作为单独USAGE_OPT选项的一部分传递,因此$opt_width设置不正确。没有函数接口Pod::Text,因此宽度与特定对象相关联$parser,而不是与一般的包相关联。您无法设置$Pod::Text::width和覆盖默认76值。默认情况下,这是硬编码在程序中的。
有一种方法可以使用Pod::Text,找到一种方法来获取终端宽度,将其传递给您的Pod::Text对象,然后使用该对象parse_from_file在源文件上调用 to 方法。
如果终端是 130 个字符宽,那么您需要做很多工作才能看到 130 个字符宽的 POD 输出。