Changeset 25424

Show
Ignore:
Timestamp:
11/30/08 18:14:50 (4 years ago)
Author:
yappo
Message:

refactoring to coerce

Location:
lang/perl/Shika/trunk
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • lang/perl/Shika/trunk/lib/Shika.pm

    r25423 r25424  
    7373            next unless exists $args->{$name}; 
    7474            next unless exists $has->{coerce} && $has->{coerce}; 
    75             Carp::croak "Shika requires CODE for cerce" unless ref $has->{coerce} eq 'CODE'; 
    76             $args->{$name} = $has->{coerce}->($args->{$name}); 
     75            die "does not pass the type constraint because: Validation failed for '$has->{isa}' failed $name" 
     76                unless Shika::Devel::TypeConstraints::check_valid($has, undef, $args->{$name}); 
    7777        } 
    7878        # process 'required' 
     
    9898sub add_attribute { 
    9999    my ($target, $name, $attr) = @_; 
     100 
     101    die "You cannot have coercion without specifying a type constraint on attribute ($name)" 
     102        if $attr->{coerce} && !$attr->{isa}; 
    100103 
    101104    no strict 'refs'; 
     
    159162        } 
    160163 
     164        if (exists $has->{isa}) { 
     165            die "does not pass the type constraint because: Validation failed for '$has->{isa}' failed $_[0]" 
     166                unless Shika::Devel::TypeConstraints::check_valid($has, @_); 
     167        } 
     168 
    161169        if (@_==2) {  
    162             return $_[0]->{$n} = $has->{coerce}->($_[1]); 
     170            return $_[0]->{$n} = $_[1]; 
    163171        } 
    164172        shift->{$n} = \@_; 
     
    197205        } 
    198206 
     207        if (exists $has->{isa}) { 
     208            die "does not pass the type constraint because: Validation failed for '$has->{isa}' failed $_[0]" 
     209                unless Shika::Devel::TypeConstraints::check_valid($has, @_); 
     210        } 
     211 
    199212        if (@_==2) {  
    200             return $_[0]->{$n} = $has->{coerce}->($_[1]); 
     213            return $_[0]->{$n} = $_[1]; 
    201214        } 
    202215        shift->{$n} = \@_; 
     
    237250        } 
    238251 
     252        if (exists $has->{isa}) { 
     253            die "does not pass the type constraint because: Validation failed for '$has->{isa}' failed $_[0]" 
     254                unless Shika::Devel::TypeConstraints::check_valid($has, @_); 
     255        } 
     256 
    239257        if (@_==2) {  
    240             return $_[0]->{$n} = $has->{coerce}->($_[1]); 
     258            return $_[0]->{$n} = $_[1]; 
    241259        } 
    242260        shift->{$n} = \@_; 
  • lang/perl/Shika/trunk/lib/Shika/Devel.pm

    r25423 r25424  
    6464 
    6565        if (@_==2) {  
    66             return $_[0]->{$n} = $has->{coerce}->($_[1]); 
     66            return $_[0]->{$n} = $_[1]; 
    6767        } 
    6868        shift->{$n} = \@_; 
     
    112112 
    113113        if (@_==2) {  
    114             return $_[0]->{$n} = $has->{coerce}->($_[1]); 
     114            return $_[0]->{$n} = $_[1]; 
    115115        } 
    116116        shift->{$n} = \@_; 
     
    162162 
    163163        if (@_==2) {  
    164             return $_[0]->{$n} = $has->{coerce}->($_[1]); 
     164            return $_[0]->{$n} = $_[1]; 
    165165        } 
    166166        shift->{$n} = \@_; 
  • lang/perl/Shika/trunk/lib/Shika/Devel/TypeConstraints.pm

    r25412 r25424  
    22use strict; 
    33use warnings; 
     4 
     5my @DEFAULT_TYPES = qw( Any Bool Maybe Undef Defined Value Num Int Str ClassName Ref ScalarRef ArrayRef HashRef CodeRef GlobeRef FileHandle Object Role ); 
    46 
    57sub import { 
     
    911    no strict 'refs'; 
    1012    *{"$caller\::subtype"} = \&_subtype; 
     13    *{"$caller\::coerce"}  = \&_coerce; 
    1114} 
    1215 
     
    1518    my($name, $code) = @_; 
    1619    $SUBTYPE->{$name} = $code; 
     20} 
     21 
     22my $COERCE = +{}; 
     23sub _coerce { 
     24    my($name, $conf) = @_; 
     25    $COERCE->{$name} = $conf; 
     26} 
     27 
     28sub _apply_coerce { 
     29    my $isa = shift; 
     30 
     31    my @types = ( $isa ); 
     32    if ($isa =~ /\|/) { # or 
     33        $isa =~ s/\s//g; 
     34        for my $type (split /\|/, $isa) { 
     35            push @types, $type; 
     36        } 
     37    } 
     38 
     39    my $arg_type; 
     40    while (my($type, $code) = each %{ $SUBTYPE }) { 
     41        next unless $code->(@_); 
     42        $arg_type = $type; 
     43        last; 
     44    } 
     45    unless ($arg_type) { 
     46        for my $type (reverse @DEFAULT_TYPES) { 
     47            next unless eval { _check($type, @_) }; 
     48            $arg_type = $type; 
     49            last; 
     50        } 
     51    } 
     52 
     53    for my $type (@types) { 
     54        next unless defined $COERCE->{$type}; 
     55        next unless defined $COERCE->{$type}->{$arg_type}; 
     56        $COERCE->{$type}->{$arg_type}->(@_); 
     57        return _check($isa, @_); 
     58    } 
    1759} 
    1860 
     
    2466    return 1 unless $isa; 
    2567    return 1 if @_ > 1 && $isa eq 'ARRAY'; 
    26     return _check($isa, @_); 
     68    _check($isa, @_) ? 1 : $has->{coerce} ? _apply_coerce($isa, @_) : 0; 
    2769} 
    2870 
  • lang/perl/Shika/trunk/t/010_core/08_coerce.t

    r25104 r25424  
    1212    package Response; 
    1313    use Shika; 
     14    use Shika::Devel::TypeConstraints; 
     15 
     16    subtype 'Headers' => sub { defined $_[0] && eval { $_[0]->isa('Headers') } }; 
     17    coerce 'Headers' => +{ 
     18        HashRef => sub { 
     19            $_[0] = Headers->new(%{ $_[0] }); 
     20        }, 
     21    }; 
     22 
    1423    has headers => ( 
    15         coerce => sub { 
    16             my $param = shift; 
    17             if (ref $param eq 'HASH') { 
    18                 Headers->new(%$param) 
    19             } else { 
    20                 $param 
    21             } 
    22         }, 
     24        isa    => 'Headers', 
     25        coerce => 1, 
    2326    ); 
    2427} 
    2528 
    26 my $r = Response->new(headers => { foo => 'bar'}); 
     29my $r = Response->new(headers => { foo => 'bar' }); 
    2730is($r->headers->foo, 'bar'); 
    2831$r->headers({foo => 'yay'}); 
  • lang/perl/Shika/trunk/tools/accessor_installer_generator.pl

    r25423 r25424  
    3232        } 
    3333 
    34 [% IF debug -%] 
     34[% IF debug || coerce -%] 
    3535        if (exists $has->{isa}) { 
    3636            die "does not pass the type constraint because: Validation failed for '$has->{isa}' failed $_[0]" 
     
    4040[% END -%] 
    4141        if (@_==2) { [%# setter %] 
    42 [% IF coerce -%] 
    43             return $_[0]->{$n} = $has->{coerce}->($_[1]); 
    44 [% ELSE -%] 
    4542            return $_[0]->{$n} = $_[1]; 
    46 [% END -%] 
    4743        } 
    4844        shift->{$n} = \@_;