Commit | Line | Data |
7a50b450 |
1 | #!/usr/bin/perl |
2 | |
3 | use strict; |
4 | use warnings; |
5 | |
6 | use Test::More tests => 8; |
7 | use Test::Exception; |
8 | |
9 | |
10 | |
11 | { |
12 | package Record; |
13 | use Mouse; |
14 | |
15 | has 'first_name' => (is => 'ro', isa => 'Str'); |
16 | has 'last_name' => (is => 'ro', isa => 'Str'); |
17 | |
18 | package RecordSet; |
19 | use Mouse; |
20 | |
21 | has 'data' => ( |
22 | is => 'ro', |
23 | isa => 'ArrayRef[Record]', |
24 | default => sub { [] }, |
25 | ); |
26 | |
27 | has 'index' => ( |
28 | is => 'rw', |
29 | isa => 'Int', |
30 | default => sub { 0 }, |
31 | ); |
32 | |
33 | sub next { |
34 | my $self = shift; |
35 | my $i = $self->index; |
36 | $self->index($i + 1); |
37 | return $self->data->[$i]; |
38 | } |
39 | |
40 | package RecordSetIterator; |
41 | use Mouse; |
42 | |
43 | has 'record_set' => ( |
44 | is => 'rw', |
45 | isa => 'RecordSet', |
46 | ); |
47 | |
48 | # list the fields you want to |
49 | # fetch from the current record |
50 | my @fields = Record->meta->get_attribute_list; |
51 | |
52 | has 'current_record' => ( |
53 | is => 'rw', |
54 | isa => 'Record', |
55 | lazy => 1, |
56 | default => sub { |
57 | my $self = shift; |
58 | $self->record_set->next() # grab the first one |
59 | }, |
60 | trigger => sub { |
61 | my $self = shift; |
62 | # whenever this attribute is |
63 | # updated, it will clear all |
64 | # the fields for you. |
65 | $self->$_() for map { '_clear_' . $_ } @fields; |
66 | } |
67 | ); |
68 | |
69 | # define the attributes |
70 | # for all the fields. |
71 | for my $field (@fields) { |
72 | has $field => ( |
73 | is => 'ro', |
74 | isa => 'Any', |
75 | lazy => 1, |
76 | default => sub { |
77 | my $self = shift; |
78 | # fetch the value from |
79 | # the current record |
80 | $self->current_record->$field(); |
81 | }, |
82 | # make sure they have a clearer .. |
83 | clearer => ('_clear_' . $field) |
84 | ); |
85 | } |
86 | |
87 | sub get_next_record { |
88 | my $self = shift; |
89 | $self->current_record($self->record_set->next()); |
90 | } |
91 | } |
92 | |
93 | my $rs = RecordSet->new( |
94 | data => [ |
95 | Record->new(first_name => 'Bill', last_name => 'Smith'), |
96 | Record->new(first_name => 'Bob', last_name => 'Jones'), |
97 | Record->new(first_name => 'Jim', last_name => 'Johnson'), |
98 | ] |
99 | ); |
100 | isa_ok($rs, 'RecordSet'); |
101 | |
102 | my $rsi = RecordSetIterator->new(record_set => $rs); |
103 | isa_ok($rsi, 'RecordSetIterator'); |
104 | |
105 | is($rsi->first_name, 'Bill', '... got the right first name'); |
106 | is($rsi->last_name, 'Smith', '... got the right last name'); |
107 | |
108 | $rsi->get_next_record; |
109 | |
110 | is($rsi->first_name, 'Bob', '... got the right first name'); |
111 | is($rsi->last_name, 'Jones', '... got the right last name'); |
112 | |
113 | $rsi->get_next_record; |
114 | |
115 | is($rsi->first_name, 'Jim', '... got the right first name'); |
116 | is($rsi->last_name, 'Johnson', '... got the right last name'); |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |