2016-09-15 6 views
1

Perl Moo 객체의 일부 필드의 경우 빈 문자열을 필드에 할당 할 때 undef으로 대체하고 싶습니다.Perl Moo 객체에서 빈 문자열을 undef로 자동 변환

내가 원한다 : $obj->x("") 필드를 x으로 지정하지 않았다.

이 작업을 수행하는 무언가 확장 프로그램을 개발하는 데 도움을주십시오.


이 할 수있는 가능한 방법 :

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 (위 링크) 위에 있습니다.