all tests now working again
[scpubgit/stemmatology.git] / lib / Text / Tradition / Collation / Reading.pm
1 package Text::Tradition::Collation::Reading;
2
3 use Moose;
4 use overload '""' => \&_stringify, 'fallback' => 1;
5 use Text::Tradition::Collation;
6
7 =head1 NAME
8
9 Text::Tradition::Collation::Reading - represents a reading (usually a word) in a collation.
10     
11 =head1 DESCRIPTION
12
13 Text::Tradition is a library for representation and analysis of collated
14 texts, particularly medieval ones.  A 'reading' refers to a unit of text,
15 usually a word, that appears in one or more witnesses (manuscripts) of the
16 tradition; the text of a given witness is composed of a set of readings in
17 a particular sequence
18
19 =head1 METHODS
20
21 =head2 new
22
23 Creates a new reading in the given collation with the given attributes. 
24 Options include:
25
26 =over 4
27
28 =item collation - The Text::Tradition::Collation object to which this reading belongs.  Required.
29
30 =item id - A unique identifier for this reading. Required.
31
32 =item text - The word or other text of the reading.
33
34 =item is_start - The reading is the starting point for the collation.
35
36 =item is_end - The reading is the ending point for the collation.
37
38 =item is_lacuna - The 'reading' represents a known gap in the text.
39
40 =item rank - The sequence number of the reading. This should probably not be set manually.
41
42 =back
43
44 One of 'text', 'is_start', 'is_end', or 'is_lacuna' is required.
45
46 =head2 collation
47
48 =head2 id
49
50 =head2 text
51
52 =head2 is_start
53
54 =head2 is_end
55
56 =head2 is_lacuna
57
58 =head2 rank
59
60 Accessor methods for the given attributes.
61
62 =cut
63
64 has 'collation' => (
65         is => 'ro',
66         isa => 'Text::Tradition::Collation',
67         # required => 1,
68         weak_ref => 1,
69         );
70
71 has 'id' => (
72         is => 'ro',
73         isa => 'Str',
74         required => 1,
75         );
76
77 has 'text' => (
78         is => 'ro',
79         isa => 'Str',
80         required => 1,
81         );
82
83 has 'is_start' => (
84         is => 'ro',
85         isa => 'Bool',
86         default => undef,
87         );
88
89 has 'is_end' => (
90         is => 'ro',
91         isa => 'Bool',
92         default => undef,
93         );
94     
95 has 'is_lacuna' => (
96     is => 'ro',
97     isa => 'Bool',
98         default => undef,
99     );
100
101 has 'rank' => (
102     is => 'rw',
103     isa => 'Int',
104     predicate => 'has_rank',
105     );
106
107
108 around BUILDARGS => sub {
109         my $orig = shift;
110         my $class = shift;
111         my $args;
112         if( @_ == 1 ) {
113                 $args = shift;
114         } else {
115                 $args = { @_ };
116         }
117         
118         # If one of our special booleans is set, we change the text and the
119         # ID to match.
120         
121         if( exists $args->{'is_lacuna'} && !exists $args->{'text'} ) {
122                 $args->{'text'} = sprintf( "#LACUNA_%s#", $args->{'id'} );
123         } elsif( exists $args->{'is_start'} ) {
124                 $args->{'id'} = '#START#';  # Change the ID to ensure we have only one
125                 $args->{'text'} = '#START#';
126                 $args->{'rank'} = 0;
127         } elsif( exists $args->{'is_end'} ) {
128                 $args->{'id'} = '#END#';        # Change the ID to ensure we have only one
129                 $args->{'text'} = '#END#';
130         }
131         
132         $class->$orig( $args );
133 };
134
135 =head2 is_meta
136
137 A meta attribute (ha ha), which should be true if any of our 'special'
138 booleans are true.  Implies that the reading does not represent a bit 
139 of text found in a witness.
140
141 =cut
142
143 sub is_meta {
144         my $self = shift;
145         return $self->is_start || $self->is_end || $self->is_lacuna;    
146 }
147
148 # Some syntactic sugar
149 sub related_readings {
150         my $self = shift;
151         return $self->collation->related_readings( $self, @_ );
152 }
153
154 sub set_identical {
155         my( $self, $other ) = @_;
156         return $self->collation->add_relationship( $self, $other, 
157                 { 'type' => 'transposition' } );
158 }
159
160 sub _stringify {
161         my $self = shift;
162         return $self->id;
163 }
164
165 no Moose;
166 __PACKAGE__->meta->make_immutable;
167
168 1;
169