5

私は小さな perl モジュールを持っていて、Getopt::Long を使用しています。Pod::Usage を使用して見栄えの良いヘルプ表示を取得することも考えました。

少しいじった後、1つの小さな例外を除いて、かなりうまく機能するようになりました. 出力の幅を設定できません。

私の端末は 191 文字幅です。perldoc Module.pm を使用すると、ドキュメントがその幅に正しくフォーマットされます。pod2usage() を使用すると、デフォルト幅の 76 文字が使用されます。

width オプションをフォーマッタに渡す方法がわかりません。ドキュメントには、BEGIN ブロックを使用して別のフォーマッタ (Pod::Text::Termcap など) を設定する方法が示されています。Term::ReadKey を使用して幅を取得しました (検証済み) が、フォーマッタを取得できません。見てください。

ヒントはありますか?

テストしようとしている完全なモジュールと、それをロードするための小さなテスト スクリプトを次に示します。意味を理解するには、妥当な幅 (132 以上なので明らかです) のターミナルを開き、「./test.pl --man」の出力と「perldoc MUD::Config」の出力を比較します。 .

perldoc が追加する man ページ スタイルのヘッダーとフッターがなくても生活できますが、端末の幅を尊重 (および使用) したいと思います。

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;
4

2 に答える 2

3

男、私は本当にこれで挑戦を探していました...

何が起こっているのかを確認するために のコードをのぞきましたPod::UsagePod::Usageコマンドを直接使用するため、両方のperldocように見え、同じように出力されます。実際、私のシステムでは、との両方がデフォルトで多かれ少なかれ 80 列になっています。システムによって異なる理由がわかりません。perldocpod2usageperldocpod2usage

例外が 1 つあります。

引数を設定すると、書式設定に-noperldoc使用され、新しいオブジェクトを作成するときにオプションがあります。Pod::TextPod::Text-width => $widthPod::Text

文書化され -widthていないパラメーターを渡すことができ、作成されるオブジェクトpod2usageに渡されると思いました。$parserこのオブジェクトはオブジェクトですPod::UsagePod::Usage、のサブクラスですPod::Text

サイコロはありません。

USAGE_OPTオプションは別のオプションの一部として渡されるため、$opt_width正しく設定されません。には機能的なインターフェイスがないためPod::Text、幅は特定のオブジェクトに関連付けられており$parser、一般にパッケージには関連付けられていません。$Pod::Text::widthデフォルト値を設定および上書きすることはできません76。これは、デフォルトでプログラムにハードコーディングされています。

を使用する方法がありPod::Text、端末の幅を取得する方法を見つけ、それをPod::Textオブジェクトに渡し、そのオブジェクトを使用しparse_from_fileてソース ファイルの to メソッドを呼び出します。

端末の幅が 130 文字の場合、POD 出力を 130 文字幅で表示できるようにするだけでも大変な作業になります。

于 2013-10-14T01:07:24.183 に答える