File Coverage

lib/List/Objects/WithUtils/Role/Hash/Typed.pm
Criterion Covered Total %
statement 15 15 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
total 20 20 100.0


line stmt bran cond sub code
1         package List::Objects::WithUtils::Role::Hash::Typed;
2 14     14 use strictures 1;
  14        
  14        
3          
4 14     14 use Carp ();
  14        
  14        
5 14     14 use Scalar::Util ();
  14        
  14        
6 14     14 use Type::Tie ();
  14        
  14        
7          
8 14     14 use Role::Tiny;
  14        
  14        
9         requires 'type', 'new';
10          
11         around type => sub { tied(%{$_[1]})->type };
12          
13         around new => sub {
14           my (undef, $class, $type) = splice @_, 0, 2;
15          
16           if (my $blessed = Scalar::Util::blessed $class) {
17             $type = $class->type;
18             $class = $blessed;
19           } else {
20             $type = shift;
21           }
22          
23           Carp::confess "Expected a Type::Tiny type but got '$type'"
24             unless Scalar::Util::blessed($type)
25             && $type->isa('Type::Tiny');
26          
27           my $self = {};
28           tie(%$self, 'Type::Tie::HASH', $type);
29           %$self = @_;
30           bless $self, $class;
31         };
32          
33         1;
34          
35         =pod
36        
37         =for Pod::Coverage new hash_of
38        
39         =head1 NAME
40        
41         List::Objects::WithUtils::Role::Hash::Typed - Type-checking hash behavior
42        
43         =head1 SYNOPSIS
44        
45         # Via List::Objects::WithUtils::Hash::Typed ->
46         use List::Objects::WithUtils 'hash_of';
47         use Types::Standard -all;
48        
49         my $arr = hash_of(Int, foo => 1, bar => 2);
50         $arr->set(baz => 3.14159); # dies, failed type check
51        
52         =head1 DESCRIPTION
53        
54         This role makes use of L<Type::Tie> to add type-checking behavior to
55         L<List::Objects::WithUtils::Role::Hash> consumers.
56        
57         The first argument passed to the constructor should be a L<Type::Tiny> type:
58        
59         use Types::Standard -all;
60         my $arr = hash_of ArrayRef() => (foo => [], bar => []);
61        
62         Values are checked against the specified type when the object is constructed
63         or new elements are added.
64        
65         If the initial type-check fails, a coercion is attempted.
66        
67         Values that cannot be coerced will throw an exception.
68        
69         Also see L<Types::Standard>, L<List::Objects::Types>
70        
71         =head2 type
72        
73         Returns the L<Type::Tiny> type the object was created with.
74        
75         =head1 AUTHOR
76        
77         Jon Portnoy <avenj@cobaltirc.org>; typed hashes implemented by Toby Inkster
78         (CPAN: TOBYINK)
79        
80         =cut
81