2016-09-15 21 views
1

Perl Mooオブジェクトのフィールドによっては、空文字列をundefというフィールドに代入するときに置き換えたいものがあります。Perl Mooオブジェクトの空文字列をundefに自動的に変換する

これは、私が欲しいのは$obj->x("")フィールドをxにすることです。

これを行うMoo拡張機能の開発にお役立てください。


は、これを行うために可能な方法:

sub make_field_undef { 
    my ($class, $field_name) = @_; 
    eval "package $class"; 
    around $field_name => sub { 
    my $orig = shift; 
    my $self = shift; 
    my @args = @_; 
    if(@args >= 1) { 
     $args[0] = undef if defined $args[0] && $args[0] eq ''; 
    } 
    $orig->($self, @args); 
    }; 
} 

をしかし、これを行うには、「より多くの構造化された」または「より宣言」の方法がありますか?これを行う他の方法はありますか?


完全な例を以下に示します。しかし、それは私が理解していないエラーを生成し実行している:

package UndefOnEmpty; 
use Moo; 

sub auto_undef_fields {() } 

sub make_fields_undef { 
    my ($class) = @_; 
    eval "package $class"; 
    around [$class->auto_undef_fields] => sub { 
    my $orig = shift; 
    my $self = shift; 
    my @args = @_; 
    if(@args >= 1) { 
     $args[0] = undef if defined $args[0] && $args[0] eq ''; 
    } 
    $orig->($self, @args); 
    }; 
    around 'BUILD' => { 
    my ($self, $args) = @_; 
    foreach my $field_name ($class->auto_undef_fields) { 
     $args->{$field_name} = undef if defined $args->{$field_name} && $args->{$field_name} eq ""; 
    } 
    }; 
} 

1; 

使用例を:ここで

#!/usr/bin/perl 

package X; 
use Moo; 
use lib '.'; 
extends 'UndefOnEmpty'; 
use Types::Standard qw(Str Int Maybe); 
use Data::Dumper; 

has 'x' => (is=>'rw', isa=>Maybe[Str]); 
has 'y' => (is=>'rw', isa=>Maybe[Str]); 

sub auto_undef_fields { qw(x y) } 
__PACKAGE__->make_fields_undef; 

my $obj = X->new(x=>""); 
$obj->y(""); 
print Dumper $obj->x, $obj->y; 

はエラーです:

$ ./test.pl 
"my" variable $class masks earlier declaration in same scope at UndefOnEmpty.pm line 20. 
"my" variable $args masks earlier declaration in same statement at UndefOnEmpty.pm line 21. 
"my" variable $field_name masks earlier declaration in same statement at UndefOnEmpty.pm line 21. 
"my" variable $args masks earlier declaration in same statement at UndefOnEmpty.pm line 21. 
"my" variable $field_name masks earlier declaration in same statement at UndefOnEmpty.pm line 21. 
syntax error at UndefOnEmpty.pm line 20, near "foreach " 
Compilation failed in require at /usr/share/perl5/Module/Runtime.pm line 317. 

の原因が何であるかを理解するのに役立ちますエラー。

+2

これはコード作成サービスではありません。特定のコードの問題を解決するのに役立ちます。あなたがすでに持っているものを見せて、あなたが問題を抱えている特定の問題領域を説明してください。 – stevieb

+1

喜んでお手伝いしますが、まだ何もしていないので、私が何を手助けすることができないのか分かりません。 – Borodin

+0

私のソリューションの試行を追加しました – porton

答えて

2

なぜcoerce属性in hasで強制変換を使用しないのですか?それは最もシンプルで簡単な方法です。

package Foo; 
use Moo; 

has bar => (
    is  => 'rw', 
    coerce => sub { $_[0] eq q{} ? undef : $_[0] }, 
); 

次にオブジェクトがどのように見えるかを示します。ムースで

package main; 
use Data::Printer; 
p my $foo1 = Foo->new(bar => q{}); 
p my $foo2 = Foo->new(bar => 123); 
p my $foo3 = Foo->new; 

__END__ 

Foo { 
    Parents  Moo::Object 
    public methods (2) : bar, new 
    private methods (0) 
    internals: { 
     bar undef 
    } 
} 
Foo { 
    Parents  Moo::Object 
    public methods (2) : bar, new 
    private methods (0) 
    internals: { 
     bar 123 
    } 
} 
Foo { 
    Parents  Moo::Object 
    public methods (2) : bar, new 
    private methods (0) 
    internals: {} 
} 

また、あなたのStrから派生し、内蔵の強制を持って、独自の型を定義することができます。次に、そのタイプのすべての属性を作成し、強制をオンにすることができます。

Mooがそのように動作するようにするには、hasのドキュメントとisaのドキュメントを参照してください。これはcoerce(上にリンクされています)のすぐ上にあります。

関連する問題