File Coverage

blib/lib/Lingua/JA/WordNet.pm
Criterion Covered Total %
statement 122 122 100.0
branch 38 38 100.0
condition 24 24 100.0
subroutine 20 20 100.0
pod 11 11 100.0
total 215 215 100.0


line stmt bran cond sub pod time code
1             package Lingua::JA::WordNet;
2              
3 15     15   339104 use 5.008_008;
  15         50  
  15         572  
4 15     15   76 use strict;
  15         60  
  15         400  
5 15     15   69 use warnings;
  15         32  
  15         401  
6              
7 15     15   1549353 use DBI;
  15         298445  
  15         1089  
8 15     15   180 use Carp ();
  15         25  
  15         243  
9 15     15   15929 use File::ShareDir ();
  15         117685  
  15         377  
10 15     15   30071 use List::MoreUtils ();
  15         83829  
  15         23543  
11              
12             our $VERSION = '0.21';
13              
14             my $DB_FILE = 'wnjpn-1.1_and_synonyms-1.0.db';
15              
16              
17             sub _options
18             {
19             return {
20 23     23   140 data => File::ShareDir::dist_file('Lingua-JA-WordNet', $DB_FILE),
21             enable_utf8 => 0,
22             verbose => 0,
23             };
24             }
25              
26             sub new
27             {
28 23     23 1 43984 my $class = shift;
29              
30 23         120 my $options = $class->_options;
31              
32 23 100       5902 if (scalar @_ == 1) { $options->{data} = shift; }
  2         6  
33             else
34             {
35 21         78 my %args = @_;
36              
37 21         80 for my $key (keys %args)
38             {
39 17 100       60 if ( ! exists $options->{$key} ) { Carp::croak "Unknown option: '$key'"; }
  1         16  
40 16         77 else { $options->{$key} = $args{$key}; }
41             }
42             }
43              
44 22 100       652 Carp::croak 'WordNet data file is not found' unless -f $options->{data};
45              
46 19         304 my $dbh = DBI->connect("dbi:SQLite:dbname=$options->{data}", '', '', {
47             #Warn => 0, # get rid of annoying disconnect message
48             # The Warn attribute enables useful warnings for certain bad practices.
49             # It is enabled by default and should only be disabled in rare circumstances.
50             # (see http://search.cpan.org/dist/DBI/DBI.pm#Warn)
51              
52             RaiseError => 1,
53             PrintError => 0,
54             AutoCommit => 0,
55             sqlite_unicode => $options->{enable_utf8},
56             });
57              
58 19         733661 bless { dbh => $dbh, verbose => $options->{verbose} }, $class;
59             }
60              
61 19     19   60333 sub DESTROY { shift->{dbh}->disconnect; }
62              
63             sub Word
64             {
65 11     11 1 9836 my ($self, $synset, $lang) = @_;
66              
67 11 100       51 $lang = 'jpn' unless defined $lang;
68              
69 11         108 my $sth
70             = $self->{dbh}->prepare
71             (
72             'SELECT lemma FROM word JOIN sense ON word.wordid = sense.wordid
73             WHERE synset = ?
74             AND sense.lang = ?'
75             );
76              
77 11         13518 $sth->execute($synset, $lang);
78              
79 11         30 my @words = map { $_->[0] =~ tr/_/ /; $_->[0]; } @{$sth->fetchall_arrayref};
  25         53  
  25         66  
  11         526  
80              
81 11 100 100     115 Carp::carp "Word: there are no words for $synset in $lang" if $self->{verbose} && ! scalar @words;
82              
83 11         850 return @words;
84             }
85              
86             sub Synset
87             {
88 9     9 1 2370 my ($self, $word, $lang) = @_;
89              
90 9 100       32 $lang = 'jpn' unless defined $lang;
91              
92 9         71 my $sth
93             = $self->{dbh}->prepare
94             (
95             'SELECT synset FROM word LEFT JOIN sense ON word.wordid = sense.wordid
96             WHERE lemma = ?
97             AND sense.lang = ?'
98             );
99              
100 9         4363 $sth->execute($word, $lang);
101              
102 9         18 my @synsets = map {$_->[0]} @{$sth->fetchall_arrayref};
  11         37  
  9         129  
103              
104 9 100 100     409 Carp::carp "Synset: there are no synsets for '$word' in $lang" if $self->{verbose} && ! scalar @synsets;
105              
106 9         806 return @synsets;
107             }
108              
109             sub SynPos
110             {
111 6     6 1 2636 my ($self, $word, $pos, $lang) = @_;
112              
113 6 100       16 $lang = 'jpn' unless defined $lang;
114              
115 6         39 my $sth
116             = $self->{dbh}->prepare
117             (
118             'SELECT synset FROM word LEFT JOIN sense ON word.wordid = sense.wordid
119             WHERE lemma = ?
120             AND word.pos = ?
121             AND sense.lang = ?'
122             );
123              
124 6         1473 $sth->execute($word, $pos, $lang);
125              
126 6         10 my @synsets = map {$_->[0]} @{$sth->fetchall_arrayref};
  6         15  
  6         61  
127              
128 6 100 100     71 Carp::carp "SynPos: there are no synsets for '$word' corresponding to '$pos' and '$lang'" if $self->{verbose} && ! scalar @synsets;
129              
130 6         688 return @synsets;
131             }
132              
133             sub Pos
134             {
135 9     9 1 571 my ($self, $synset) = @_;
136 9 100       61 return $1 if $synset =~ /^[0-9]{8}-([arnv])$/;
137 5 100       59 Carp::carp "Pos: '$synset' is wrong synset format" if $self->{verbose};
138 5         1512 return;
139             }
140              
141             sub Rel
142             {
143 5     5 1 2403 my ($self, $synset, $rel) = @_;
144              
145 5         39 my $sth
146             = $self->{dbh}->prepare
147             (
148             'SELECT synset2 FROM synlink
149             WHERE synset1 = ?
150             AND link = ?'
151             );
152              
153 5         1280 $sth->execute($synset, $rel);
154              
155 5         12 my @synsets = map {$_->[0]} @{$sth->fetchall_arrayref};
  3         11  
  5         59  
156              
157 5 100 100     64 Carp::carp "Rel: there are no $rel links for $synset" if $self->{verbose} && ! scalar @synsets;
158              
159 5         790 return @synsets;
160             }
161              
162             sub Def
163             {
164 9     9 1 8901 my ($self, $synset, $lang) = @_;
165              
166 9 100       32 $lang = 'jpn' unless defined $lang;
167              
168 9         76 my $sth
169             = $self->{dbh}->prepare
170             (
171             'SELECT sid, def FROM synset_def
172             WHERE synset = ?
173             AND lang = ?'
174             );
175              
176 9         2067 $sth->execute($synset, $lang);
177              
178 9         17 my @defs;
179              
180 9         122 while (my $row = $sth->fetchrow_arrayref)
181             {
182 13         18 my ($sid, $def) = @{$row};
  13         29  
183 13         133 $defs[$sid] = $def;
184             }
185              
186 9 100 100     69 Carp::carp "Def: there are no definition sentences for $synset in $lang" if $self->{verbose} && ! scalar @defs;
187              
188 9         751 return @defs;
189             }
190              
191             sub Ex
192             {
193 9     9 1 8198 my ($self, $synset, $lang) = @_;
194              
195 9 100       35 $lang = 'jpn' unless defined $lang;
196              
197 9         71 my $sth
198             = $self->{dbh}->prepare
199             (
200             'SELECT sid, def FROM synset_ex
201             WHERE synset = ?
202             AND lang = ?'
203             );
204              
205 9         2931 $sth->execute($synset, $lang);
206              
207 9         48 my @exs;
208              
209 9         118 while (my $row = $sth->fetchrow_arrayref)
210             {
211 12         19 my ($sid, $ex) = @{$row};
  12         30  
212 12         101 $exs[$sid] = $ex;
213             }
214              
215 9 100 100     86 Carp::carp "Ex: there are no example sentences for $synset in $lang" if $self->{verbose} && ! scalar @exs;
216              
217 9         1085 return @exs;
218             }
219              
220             sub AllSynsets
221             {
222 1     1 1 8 my $self = shift;
223 1         12 my $sth = $self->{dbh}->prepare('SELECT synset FROM synset');
224 1         743 $sth->execute;
225 1         3 my @synsets = map {$_->[0]} @{$sth->fetchall_arrayref};
  117659         195079  
  1         172319  
226 1         27742 return \@synsets;
227             }
228              
229             sub WordID
230             {
231 22     22 1 11146 my ($self, $word, $pos, $lang) = @_;
232              
233 22         33 $word =~ tr/ /_/;
234 22 100       61 $lang = 'jpn' unless defined $lang;
235              
236 22         125 my $sth
237             = $self->{dbh}->prepare
238             (
239             'SELECT wordid FROM word
240             WHERE lemma = ?
241             AND pos = ?
242             AND lang = ?'
243             );
244              
245 22         3484 $sth->execute($word, $pos, $lang);
246              
247 22         33 my ($wordid) = map {$_->[0]} @{$sth->fetchall_arrayref};
  19         51  
  22         218  
248              
249 22 100 100     157 Carp::carp "WordID: there is no WordID for '$word' corresponding to '$pos' and '$lang'" if $self->{verbose} && ! defined $wordid;
250              
251 22         857 return $wordid;
252             }
253              
254             sub Synonym
255             {
256 14     14 1 3964 my ($self, $wordid) = @_;
257              
258 14         73 my $sth
259             = $self->{dbh}->prepare
260             (
261             'SELECT lemma FROM word JOIN wordlink ON word.wordid = wordlink.wordid2
262             WHERE wordid1 = ?
263             AND link = ?'
264             );
265              
266 14         1784 $sth->execute($wordid, 'syns');
267 14         24 my @synonyms = map {$_->[0]} @{$sth->fetchall_arrayref};
  43         82  
  14         688  
268              
269 14 100 100     114 Carp::carp "Synonyms: there are no Synonyms for $wordid" if $self->{verbose} && ! scalar @synonyms;
270              
271             # 一応順番を保持したいのでハッシュスライスは使わない
272             # uniq: The order of elements in the returned list is the same as in LIST.
273 14         801 return List::MoreUtils::uniq @synonyms;
274             }
275              
276             1;
277              
278             __END__