2010-07-08 14 views
6

Tôi thấy bản thân mình liên tục viết và viết lại các loại mã sau đây:Có mô-đun Perl nào để thiết lập một đối tượng từ cấu hình mặc định cộng với băm nhỏ của cấu hình tùy chọn không?

my %default = (x => "a", y => "b"); 
sub new 
{ 
     my ($package, $config) = @_; 
     my $self = {%default}; 
     for my $k (keys %default) { 
      $self->{$k} = $config->{$k} if defined $config->{$k}; 
     } 
     for my $k (keys %$config) { 
      if (! exists $default{$k}) { 
       carp "Unknown config option $k\n"; 
      } 
     } 
     bless $self; 
     # etc. etc. 
} 

Trước khi tôi làm cho mô-đun riêng của tôi để làm điều này, tôi chỉ tự hỏi nếu có bất cứ điều gì đã có trên CPAN như vậy? Tôi chỉ muốn chức năng này rất đơn giản ở trên, vì vậy đề xuất sử dụng Moose không phải là câu trả lời phù hợp cho câu hỏi này.

Trả lời

4

Params::Validate có thể giúp đỡ một số. Nó sẽ cho phép bạn thả hàm băm %defaults và chỉ định mặc định cho mỗi tham số (có thể tùy chọn).

Ngoài ra, bạn có thể làm cho tiết kiệm chi tiết hơn một chút bằng cách sử dụng map. Tất nhiên, điều này sẽ âm thầm bỏ qua các đối số không hợp lệ.

#!/usr/bin/perl 

package My::Class; 

use strict; use warnings; 

my %defaults = (x => 'a', y => 'b'); 

sub new { 
    my $class = shift; 
    my ($args) = @_; 

    my $self = { 
     %defaults, 
     map { 
      exists $args->{$_} ? ($_ => $args->{$_}) :() 
     } keys %defaults, 
    }; 

    return bless $self, $class; 
} 

package main; 

use strict; use warnings; 

my $x = My::Class->new({ x => 1, z => 10}); 

use YAML; 
print Dump $x; 

Output:

--- !!perl/hash:My::Class 
x: 1 
y: b
+1

OK Tôi chấp nhận không thực sự là một câu trả lời vì vậy chấp nhận cho đề cập Params :: Validate, có thể là điều gần nhất với những gì tôi hỏi về. –

+0

;-) - Cảm ơn bạn. –

11

Moose hỗ trợ mặc định cho thuộc tính, ví dụ:

has 'foo' => (is => 'rw', isa => 'Int', default => 42); 

Nhưng nếu bạn không muốn đi xuống con đường Moose, một cách đơn giản hơn để đạt được những gì bạn muốn là:

sub new { 
    my ($package, %config) = @_; 

    my %defaults = (x => 'a', y => 'b'); 

    my $self = { %defaults, %config }; 

    # error checking here 

    return bless $self, $package; 
} 

Kể từ khi chỉ định cùng một khóa băm hai lần trong quá trình khởi tạo băm sẽ ghi đè lần đầu tiên, bất kỳ phím nào trong %config sẽ chỉ ghi đè những số đó trong %defaults.

+1

Thanks for the tip với băm gấp đôi. Tôi chắc chắn cần phải kiểm tra các công cụ đi lạc trong% config quá mặc dù. –

+1

Thủ thuật băm tăng gấp đôi trông rất đẹp và có vẻ phù hợp với tôi, nhưng với perldata bất ngờ của tôi không thực sự nói điều gì sẽ xảy ra khi một băm được gán một danh sách chứa các khóa trùng lặp. Bạn có bất kỳ tài liệu cho nó? –

+3

@random, có một đề cập ngắn gọn về nó trong 'perlfaq4', hãy xem" Làm thế nào tôi có thể nhận được các khóa duy nhất từ ​​hai băm? " tại http://perldoc.perl.org/perlfaq4.html#How-can-I-get-the-unique-keys-from-two-hashes? – friedo

3

Nếu bạn đã sử dụng Moose trong mô-đun của mình, bạn có thể thực hiện hành vi này bằng cách kết hợp MooseX::GetoptMooseX::SimpleConfig. tập tin cấu hình của bạn có thể chứa giá trị mặc định, và sau đó bạn ghi đè lên bất cứ điều gì khi cần thiết bằng cách thông qua những giá trị cho các nhà xây dựng:

my $obj = Class->new_with_options(configfile => "myconfig.yaml", key1 => 'val', key2 => 'val'); 

package Class; 
use Moose; 
with 'MooseX::Getopt::Strict', 
    'MooseX::SimpleConfig'; 

has configfile => (
    is => 'ro', isa => 'Str', 
    traits => ['Getopt'], 
    documentation => 'File containing default configs', 
    lazy => 1, 
    default => sub { File::Spec->catfile($base_dir, 'my_default_config.yaml') }, 
); 

has [ qw(key1 key2) ] => (
    is => 'ro', isa => 'Str', 
); 
Các vấn đề liên quan