我有一个小的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");
和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;
伙计,我真的很想在这方面寻找挑战......
我查看了代码,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 输出。