Perl Moose - Какие аргументы при загрузке оцениваются из файлов конфигурации? - PullRequest
2 голосов
/ 20 марта 2012

В моем предыдущем вопросе Moose - загрузка значений из файлов conf ... Джек Мани был достаточно любезен, чтобы привести пример того, как это сделать с помощью Moose.

Чтобы сделать объект конфигурации еще более общим, я решил использовать Config :: Auto .

Проблема в том, что я все еще очень зеленый относительно того, как Mooseработает.Например, пример Джека:

package My::Module;
use Moose;

has 'config'=>(isa=>'HashRef[Str]',is=>'rw',required=>1);

around BUILDARGS=>sub
{
  my $orig=shift;
  my $class=shift;
  my $args=shift; #other arguments passed in (if any).

  my %config_hash=();
  open(my $read,"<","config_file") or confess $!;
  while(<$read>)
  {
    chomp;
    my @array=split /:/;
    $config_hash{$array[0]}=$array[1];
  }
  close($read);

  $args->{config}=\%config_hash;

  return $class->$orig($args);
};

no Moose;
1;

Я изменил это так:

#!/usr/local/bin/perl
package DART::Setup;

use namespace::autoclean;
use Moose;
use Config::Auto;

our $VERSION = '0.0.1';


has 'EMPTY' => ( isa => 'Str', is => 'ro', default => q{} );
has 'PPLTESTEXECUTIONID' => ( isa => 'Int', is => 'ro', default => 0 );
has 'SARQTESTEXECUTIONID' => ( isa => 'Int', is => 'ro', default => 0 );
has 'ISPROXY' => ( isa => 'Int', is => 'ro', default => 0 );
has 'LOCALHOST' => ( isa => 'Str', is => 'ro', default => '127.0.0.1' );
has 'config'=>(isa=>'HashRef[Str]',is=>'rw',required=>1);
has 'SSO' => ( isa => 'Str', is => 'rw', default => q{} );
has 'cookieFile' => ( isa => 'Str', is => 'rw', default => q{} );

around BUILDARGS=>sub
{
  my $orig=shift;
  my $class=shift;
  my $args=shift;

  my $cfg = Config::Auto::parse($args);
  my %config_hash = %{$cfg};

  $args->{config}=\%config_hash;

  return $class->$orig($args);
};


return 1;

Но, если честно, я не уверен, что я здесь делаю.Во-первых, сколько аргументов мне нужно предоставить при создании нового объекта установки?Должен ли я просто передать ему путь к моему файлу конфигурации, что-то вроде:

my $newConfig = DART::Setup->new('/home/y/conf/MyApp/MyApp.cfg');

Или мне нужно предоставить аргументы для $ orig и $ class?

Наконец, как мне теперьполучить доступ к моим недавно загруженным конфигурациям?Могу ли я сделать что-то вроде:

my %configHash = %{$newConfig->config()};

foreach my $key (keys %configHash) {
print "the key is, $key, and the value is: $configHash{$key}\n";
}

Правильно ли я понимаю?

Ответы [ 2 ]

1 голос
/ 20 марта 2012

BUILDARGS - это просто способ подключиться к конструктору в начале построения. Для справки, раздел конструкции руководства может помочь вам в этом разобраться.

Ответ Джека Мани в порядке. Основываясь на его предложении использовать атрибут config_file, вот альтернатива, которая использует ленивый строитель . Лично я предпочитаю это BUILDARGS, потому что код немного проще. Построители используются для установки значения атрибута по умолчанию. Вам нужно сделать его ленивым, потому что построение атрибута зависит от другого атрибута (в данном случае config_file), чтобы гарантировать, что построение объекта завершено и атрибут установлен.

package DART::Setup;

use namespace::autoclean;
use Moose;
use MooseX::FileAttribute;
use Config::Auto;

# use MooseX::FileAttribute (optional) to enforce that the file actually exists
#  - just a shortcut to remove some boilerplate code if you want
has_file 'config_file' => (
    is         => 'ro',
    must_exist => 1,
    required   => 1,
);

has 'config' => (
    isa      => 'HashRef[Str]', 
    is       => 'ro',
    # disallow this attribute to be set by the constructor
    init_arg => undef,
    # cause this attribute to be set up after construction
    lazy     => 1,
    builder  => '_build_config',
    # or alternatively, use 'default' instead of 'builder'
    # (but it still needs to be lazy)
    #default  => sub { Config::Auto::parse( shift->config_file ) },
);

sub _build_config {
    my ( $self ) = @_;
    my $config = Config::Auto::parse( $self->config_file );
    return $config;
}
1 голос
/ 20 марта 2012

Хорошо, внутри BUILDARGS вы хотите прочитать в файле конфигурации и передать пары ключ-значение в атрибут config.Вот модифицированная версия с другим атрибутом для файла конфигурации.

package My::Module;
use Moose;
use Config::Auto;

has 'config'=>(isa=>'HashRef[Str]',is=>'rw',required=>1);

has 'config_file'=>(isa=>'Str',is=>'ro');

around BUILDARGS=>sub
{
  my $orig=shift;
  my $class=shift;
  my $args=shift; #currently {config_file=>'/path/to/file/config_file.conf'} (or whatever)

  #make sure we've been passed a config file
  confess "No config file found in BUILDARGS" unless defined $args->{config_file};

  #Now, we open the user-specified config file via Config::Any
  my $ca=Config::Auto->new(source=>$args->{config_file},format=>"colon");
  my $parsed=$ca->parse; #hash reference containing the parsed data.

  #Now, we add this to our arguments that will become our attributes:

  $args->{config}=$parsed;

  return $class->$orig($args);
}

no Moose;
1;

Главное, что нужно понять о BUILDARGS, - это то, что он принимает следующие аргументы: имена класса и оригинальный конструктор (которые передаютсяMoose::Object), а затем любые другие аргументы, передаваемые конструктору.Итак, если вы позвоните

my $mm=My::Module->new({config_file=>"/path/to/file/file.conf"});

Затем, в BUILDARGS, у нас изначально будет

$args=={config_file=>"/path/to/file/file.conf"}

Но после анализа файла и добавления ссылки на хэш $parsed он превращается в

$args=={config_file=>"/path/to/file/file.conf",config=>{server=>"mozilla.org",protocol=>"HTTP",...}}

и т. Д. И т. Д.

При написании my $cfg = Config::Auto::parse($args); внутри BUILDARGS вы пытаетесь передать аргумент config_file парсеру в Config::Auto, ион понятия не имеет, что с ним делать.

...