File Coverage

blib/lib/Lingua/Phonology.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -w
2              
3             package Lingua::Phonology;
4              
5             $VERSION = 0.35_03;
6              
7 8     8   223510 use strict;
  8         47  
  8         335  
8 8     8   51 use warnings;
  8         34  
  8         241  
9 8     8   67 use warnings::register;
  8         13  
  8         1774  
10              
11 8     8   51 use Carp qw/carp croak/;
  8         14  
  8         909  
12 8     8   9104 use Lingua::Phonology::Common;
  0            
  0            
13             use Lingua::Phonology::Features;
14             use Lingua::Phonology::Segment;
15             use Lingua::Phonology::Symbols;
16             use Lingua::Phonology::Rules;
17             use Lingua::Phonology::Syllable;
18              
19              
20             =head1 NAME
21              
22             Lingua::Phonology - an object model for lingistic phonology and sound change
23              
24             =head1 SYNOPSIS
25              
26             use Lingua::Phonology;
27             $phono = new Lingua::Phonology;
28              
29             # Get sub-objects
30             $features = $phono->features;
31             $symbols = $phono->symbols;
32             $rules = $phono->rules;
33             $syllabification = $phono->syllable;
34             $segment = $phono->segment;
35              
36             # Load phonology defaults
37             $phono->loadfile;
38              
39             # Load a phonology definition from a file
40             $phono->loadfile('language.xml');
41              
42             # Save phonology definition to a file
43             $phono->savefile('language.xml');
44              
45             =head1 ABSTRACT
46              
47             Lingua::Phonology is a unified module for handling phonological descriptions
48             and units. It includes sub-modules for hierarchical (feature-geometric) sets of
49             features, phonetic or orthographic symbols, individual segments, linguistic
50             rules, syllabification algorithms, etc. It is written as an object-oriented
51             module, wherein one will generally have a single object for the list of
52             features, one for the phonetic symbols, one for the set of rules, etc., and
53             multiple segment objects to be programatically manipulated.
54              
55             =cut
56              
57             # Remainder of POD is after the __END__ token
58              
59             sub err ($) { warnings::warnif(shift); return; };
60              
61             # Constructor - creates new (empty) objects
62             sub new {
63             my $proto = shift;
64             my $class = ref($proto) || $proto;
65             my $self = bless {}, $class;
66              
67             $self->{FEATURES} = Lingua::Phonology::Features->new();
68             $self->{SYMBOLS} = Lingua::Phonology::Symbols->new($self->{FEATURES});
69             $self->{RULES} = Lingua::Phonology::Rules->new();
70             $self->{SYLLABLE} = Lingua::Phonology::Syllable->new();
71              
72             return $self;
73             }
74              
75             # Next section deals w/ making accessor methods
76             # Accessor methods to create and/or iterate over (order may be significant!)
77             my @accessors = qw/features symbols syllable rules/;
78              
79             # Object types to create/expect--all accessors must be defined here
80             my %classes = (
81             features => 'Lingua::Phonology::Features',
82             symbols => 'Lingua::Phonology::Symbols',
83             rules => 'Lingua::Phonology::Rules',
84             syllable => 'Lingua::Phonology::Syllable'
85             );
86              
87             # Continuations (if needed)
88             my %continue = (
89             features => sub { $_[0]->{SYMBOLS}->features($_[1]) if defined $_[1] }
90             );
91              
92             # Create methods for each of the accessors
93             while (my ($name, $class) = each %classes) {
94             my $key = uc $name;
95             no strict 'refs';
96             *$name = sub {
97             return $_[0]->{$key} unless @_ > 1;
98             my ($self, $val) = @_;
99             croak "Argument to $name() not a $class" unless _is($val, $class);
100             $self->{$key} = $val;
101             $continue{$name}->(@_) if exists $continue{$name};
102             return $self->{$key};
103             };
104             }
105            
106             # Get blank segments
107             sub segment {
108             my $self = shift;
109             my $seg = Lingua::Phonology::Segment->new($self->{FEATURES});
110             $seg->symbolset($self->{SYMBOLS});
111             return $seg;
112             }
113              
114             # Load a complete phonology definition from a file
115             sub loadfile {
116             my ($self, $file) = @_;
117             my $err = 0;
118              
119             # If called with one argument, load defaults. Submodules implement
120             # "default" in different ways--that's their problem. They must do the right
121             # thing when loadfile() is called on them with no arguments.
122             if (not defined $file) {
123             for (@accessors) {
124             $self->$_->loadfile or $err = 1;
125             }
126             }
127              
128             # When given an actual filename
129             else {
130             my $parse;
131             eval { $parse = _parse_from_file $file };
132             return err($@) unless $parse;
133              
134             for (@accessors) {
135             $self->$_->_load_from_struct($parse->{$_}) or $err = 1;
136             }
137             }
138              
139             # $return should
140             return $err ? () : 1;
141             }
142              
143             # Save a total phonology. We do this by concatenating the strings returned by
144             # the to_str() methods in the various submodules.
145             sub savefile {
146             my ($self, $file) = @_;
147              
148             my $str = '';
149             for (@accessors) {
150             $str .= "\n" . $self->$_->_to_str;
151             }
152             $str = "\n$str\n";
153              
154             eval { $file = _to_handle($file, '>') };
155             return err($@) if $@;
156              
157             print $file $str;
158             return $str;
159             }
160              
161             1;
162              
163             __END__