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