File Coverage

blib/lib/Acme/AjiFry.pm
Criterion Covered Total %
statement 40 176 22.7
branch 2 114 1.7
condition 0 18 0.0
subroutine 13 26 50.0
pod 3 5 60.0
total 58 339 17.1


line stmt bran cond sub pod time code
1             package Acme::AjiFry;
2              
3 4     4   79452 use warnings;
  4         10  
  4         108  
4 4     4   20 use strict;
  4         6  
  4         105  
5 4     4   2026 use utf8;
  4         20  
  4         22  
6 4     4   4144 use Encode;
  4         14504  
  4         306  
7 4     4   24 use List::Util;
  4         7  
  4         912  
8              
9             our $VERSION = '0.09';
10              
11 4         805 use constant COLS => {
12             a => [
13             'あ', 'か', 'さ', 'た', 'な', 'は', 'ま', 'や', 'ら', 'わ',
14             'が', 'ざ', 'だ', 'ば', 'ぱ', 'ぁ', 'ゃ', 'ゎ'
15             ],
16             i => [
17             'い', 'き', 'し', 'ち', 'に', 'ひ', 'み', 'り',
18             'ぎ', 'じ', 'ぢ', 'び', 'ぴ', 'ぃ'
19             ],
20             u => [
21             'う', 'く', 'す', 'つ', 'ぬ', 'ふ', 'む', 'ゆ', 'る', 'ぐ',
22             'ず', 'づ', 'ぶ', 'ぷ', 'ぅ', 'っ', 'ゅ'
23             ],
24             e => [
25             'え', 'け', 'せ', 'て', 'ね', 'へ', 'め', 'れ',
26             'げ', 'ぜ', 'で', 'べ', 'ぺ', 'ぇ',
27             ],
28             o => [
29             'お', 'こ', 'そ', 'と', 'の', 'ほ', 'も', 'よ', 'ろ', 'を',
30             'ご', 'ぞ', 'ど', 'ぼ', 'ぽ', 'ぉ', 'ょ'
31             ],
32             n => ['ん'],
33 4     4   19 };
  4         8  
34 4         374 use constant ROWS => {
35             a =>
36             [ 'あ', 'い', 'う', 'え', 'お', 'ぁ', 'ぃ', 'ぅ', 'ぇ', 'ぉ' ],
37             k =>
38             [ 'か', 'き', 'く', 'け', 'こ', 'が', 'ぎ', 'ぐ', 'げ', 'ご' ],
39             s =>
40             [ 'さ', 'し', 'す', 'せ', 'そ', 'ざ', 'じ', 'ず', 'ぜ', 'ぞ' ],
41             t => [
42             'た', 'ち', 'つ', 'て', 'と', 'だ',
43             'ぢ', 'づ', 'で', 'ど', 'っ'
44             ],
45             n => [ 'な', 'に', 'ぬ', 'ね', 'の' ],
46             h => [
47             'は', 'ひ', 'ふ', 'へ', 'ほ', 'ば', 'び', 'ぶ',
48             'べ', 'ぼ', 'ぱ', 'ぴ', 'ぷ', 'ぺ', 'ぽ'
49             ],
50             m => [ 'ま', 'み', 'む', 'め', 'も' ],
51             y => [ 'や', 'ゆ', 'よ', 'ゃ', 'ゅ', 'ょ' ],
52             r => [ 'ら', 'り', 'る', 'れ', 'ろ' ],
53             w => [ 'わ', 'を', 'ゎ' ],
54 4     4   16 };
  4         7  
55 4         228 use constant DULLNESS => [
56             'が', 'ぎ', 'ぐ', 'げ', 'ご', 'ざ', 'じ', 'ず', 'ぜ', 'ぞ',
57             'だ', 'ぢ', 'づ', 'で', 'ど', 'ば', 'び', 'ぶ', 'べ', 'ぼ'
58 4     4   18 ];
  4         210  
59 4     4   20 use constant P_SOUND => [ 'ぱ', 'ぴ', 'ぷ', 'ぺ', 'ぽ' ];
  4         14  
  4         234  
60 4         8655 use constant DOUBLE_CONSONANT =>
61 4     4   37 [ 'ぁ', 'ぃ', 'ぅ', 'ぇ', 'ぉ', 'っ', 'ゃ', 'ゅ', 'ょ', 'ゎ' ];
  4         7  
62              
63             sub new {
64 3     3 1 40 my $class = shift;
65 3         10 return $class;
66             }
67              
68             sub to_AjiFry {
69 2     2 1 16 my ( $self, $raw_string ) = @_;
70              
71 2         9 my $chomped = chomp($raw_string);
72 2 50       8 unless ($raw_string) {
73 0 0       0 return "\n" if $chomped;
74 0         0 return '';
75             }
76              
77 2         12 $raw_string = decode_utf8($raw_string);
78 0         0 my $ajifry_word = $self->_to_ajifry($raw_string);
79 0 0       0 $ajifry_word .= "\n" if $chomped;
80 0         0 return encode_utf8($ajifry_word);
81             }
82              
83             sub translate_to_ajifry {
84 0     0 0 0 my ( $self, $raw_string ) = @_;
85 0         0 return $self->to_AjiFry($raw_string);
86             }
87              
88             sub to_Japanese {
89 1     1 1 6 my ( $self, $ajifry_word ) = @_;
90 1         4 my $chomped = chomp($ajifry_word);
91              
92 1 50       4 unless ($ajifry_word) {
93 0 0       0 return "\n" if $chomped;
94 0         0 return '';
95             }
96              
97 1         7 $ajifry_word = decode_utf8($ajifry_word);
98 0           my $japanese_word = $self->_to_Japanese($ajifry_word);
99 0 0         $japanese_word .= "\n" if $chomped;
100 0           return encode_utf8($japanese_word);
101             }
102              
103             sub translate_from_ajifry {
104 0     0 0   my ( $self, $ajifry_word ) = @_;
105 0           return $self->to_Japanese($ajifry_word);
106             }
107              
108             sub _search_key_of_element {
109 0     0     my ( $self, $element, $hash ) = @_;
110              
111 0           foreach my $key ( sort keys %$hash ) {
112 0 0   0     if ( List::Util::first { $_ eq $element } @{ $hash->{$key} } ) {
  0            
  0            
113 0           return $key;
114             }
115             }
116             }
117              
118             sub _find_first {
119 0     0     my ( $self, $key, $list ) = @_;
120              
121 0 0   0     return ( List::Util::first { $_ eq $key } @$list ) ? 1 : 0;
  0            
122             }
123              
124             sub _find_duplicate_element_in_both_lists {
125 0     0     my $self = shift;
126 0           my ( $list_A, $list_B ) = @_;
127              
128 0           my @duplicate_elements;
129 0           foreach my $element_A ( @{$list_A} ) {
  0            
130 0           foreach my $element_B ( @{$list_B} ) {
  0            
131 0 0         if ( $element_A eq $element_B ) {
132 0           push( @duplicate_elements, $element_A );
133             }
134             }
135             }
136 0           return @duplicate_elements;
137             }
138              
139             sub _get_ajifry_word_by_consonant {
140 0     0     my $self = shift;
141 0           my $consonant = shift;
142              
143 0 0         if ( $consonant eq 'a' ) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
144 0           return "食え";
145             }
146             elsif ( $consonant eq 'k' ) {
147 0           return "フライ";
148             }
149             elsif ( $consonant eq 's' ) {
150 0           return "お刺身";
151             }
152             elsif ( $consonant eq 't' ) {
153 0           return "アジ";
154             }
155             elsif ( $consonant eq 'n' ) {
156 0           return "ドボ";
157             }
158             elsif ( $consonant eq 'h' ) {
159 0           return "山岡";
160             }
161             elsif ( $consonant eq 'm' ) {
162 0           return "岡星";
163             }
164             elsif ( $consonant eq 'y' ) {
165 0           return "ゴク・・・";
166             }
167             elsif ( $consonant eq 'r' ) {
168 0           return "ああ";
169             }
170             elsif ( $consonant eq 'w' ) {
171 0           return "雄山";
172             }
173             else {
174 0           return "";
175             }
176             }
177              
178             sub _get_ajifry_word_by_vowel {
179 0     0     my $self = shift;
180 0           my $vowel = shift;
181              
182 0 0         if ( $vowel eq 'a' ) {
    0          
    0          
    0          
    0          
    0          
183 0           return "食え食え";
184             }
185             elsif ( $vowel eq 'i' ) {
186 0           return "ドボドボ";
187             }
188             elsif ( $vowel eq 'u' ) {
189 0           return "お刺身";
190             }
191             elsif ( $vowel eq 'e' ) {
192 0           return "むむ・・・";
193             }
194             elsif ( $vowel eq 'o' ) {
195 0           return "アジフライ";
196             }
197             elsif ( $vowel eq 'n' ) {
198 0           return "京極";
199             }
200             else {
201 0           return "";
202             }
203             }
204              
205             sub _get_consonant_by_ajifry_word {
206 0     0     my $self = shift;
207 0           my $ajifry_word = shift;
208              
209 0 0 0       if ( $ajifry_word eq '食え' ) {
    0 0        
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
210 0           return 'a';
211             }
212             elsif ( $ajifry_word eq 'フライ' ) {
213 0           return 'k';
214             }
215             elsif ( $ajifry_word eq 'お刺身' ) {
216 0           return 's';
217             }
218             elsif ( $ajifry_word eq 'アジ' ) {
219 0           return 't';
220             }
221             elsif ( $ajifry_word eq 'ドボ' ) {
222 0           return 'n';
223             }
224             elsif ( $ajifry_word eq '山岡' ) {
225 0           return 'h';
226             }
227             elsif ( $ajifry_word eq '岡星' ) {
228 0           return 'm';
229             }
230             elsif ($ajifry_word eq 'ゴク・・・'
231             || $ajifry_word eq 'ゴク・・・'
232             || $ajifry_word eq 'ゴク…' )
233             {
234 0           return 'y';
235             }
236             elsif ( $ajifry_word eq 'ああ' ) {
237 0           return 'r';
238             }
239             elsif ( $ajifry_word eq '雄山' ) {
240 0           return 'w';
241             }
242             else {
243 0           return;
244             }
245             }
246              
247             sub _get_vowel_by_ajifry_word {
248 0     0     my $self = shift;
249 0           my $ajifry_word = shift;
250              
251 0 0 0       if ( $ajifry_word eq '食え食え' ) {
    0 0        
    0          
    0          
    0          
252 0           return 'a';
253             }
254             elsif ( $ajifry_word eq 'ドボドボ' ) {
255 0           return 'i';
256             }
257             elsif ( $ajifry_word eq 'お刺身' ) {
258 0           return 'u';
259             }
260             elsif ($ajifry_word eq 'むむ・・・'
261             || $ajifry_word eq 'むむ・・・'
262             || $ajifry_word eq 'むむ…' )
263             {
264 0           return 'e';
265             }
266             elsif ( $ajifry_word eq 'アジフライ' ) {
267 0           return 'o';
268             }
269             else {
270 0           return;
271             }
272             }
273              
274             sub _to_ajifry {
275 0     0     my $self = shift;
276 0           my $raw_string = shift;
277              
278 0           my @raw_chars = split //, $raw_string;
279 0           my $ajifry_word;
280 0           foreach my $raw_char (@raw_chars) {
281 0           my $vowel = $self->_search_key_of_element( $raw_char, COLS );
282 0           my $consonant = $self->_search_key_of_element( $raw_char, ROWS );
283              
284 0 0 0       if ( !$vowel && !$consonant ) {
285 0           $ajifry_word .= $raw_char; # not HIRAGANA
286 0           next;
287             }
288              
289 0 0         $ajifry_word .= "中川"
290             if $self->_find_first( $raw_char, DOUBLE_CONSONANT );
291 0           $ajifry_word .= $self->_get_ajifry_word_by_consonant($consonant);
292 0           $ajifry_word .= $self->_get_ajifry_word_by_vowel($vowel);
293 0 0         $ajifry_word .= "社主" if $self->_find_first( $raw_char, P_SOUND );
294 0 0         $ajifry_word .= "陶人" if $self->_find_first( $raw_char, DULLNESS );
295             }
296 0           return $ajifry_word;
297             }
298              
299             sub _to_Japanese {
300 0     0     my $self = shift;
301 0           my $ajifry_word = shift;
302              
303 0           my $translated_word;
304 0           while (1) {
305 0 0         unless ($ajifry_word) {
306 0           last;
307             }
308              
309 0           my $is_double_consonant = 0;
310 0 0         if ( $ajifry_word =~ s/^京極// ) {
    0          
311 0           $translated_word .= 'ん';
312 0           next;
313             }
314             elsif ( $ajifry_word =~ s/^中川// ) {
315 0           $is_double_consonant = 1;
316             }
317              
318 0           my $consonant;
319 0 0         if ( $ajifry_word =~ s/^(食え|フライ|お刺身|アジ|ドボ|山岡|岡星|ゴク・・・|ゴク・・・|ゴク…|ああ|雄山)//
320             )
321             {
322 0           $consonant = $1;
323             }
324 0 0         unless ($consonant) {
325 0           $ajifry_word =~ s/^(.)//;
326 0           $translated_word .= $1;
327 0           next;
328             }
329 0           my $vowel;
330 0 0         if ( $ajifry_word =~ s/^(食え食え|ドボドボ|お刺身|むむ・・・|むむ・・・|むむ…|アジフライ)//
331             )
332             {
333 0           $vowel = $1;
334             }
335 0 0         unless ($vowel) {
336 0           $translated_word .= $consonant;
337 0           $ajifry_word =~ s/^(.)//;
338 0           $translated_word .= $1;
339 0           next;
340             }
341              
342 0           my $is_dullness;
343 0 0         $is_dullness = $1 if $ajifry_word =~ s/^(陶人)//;
344 0           my $is_p_sound;
345 0 0         $is_p_sound = $1 if $ajifry_word =~ s/^(社主)//;
346              
347 0           $consonant = $self->_get_consonant_by_ajifry_word($consonant);
348 0           $vowel = $self->_get_vowel_by_ajifry_word($vowel);
349              
350 0           my @match_characters =
351             $self->_find_duplicate_element_in_both_lists( ROWS->{$consonant},
352             COLS->{$vowel} );
353 0 0 0       if ($is_p_sound) {
    0          
    0          
    0          
354 0           $translated_word .= $match_characters[2];
355             }
356             elsif ($is_dullness) {
357 0           $translated_word .= $match_characters[1];
358             }
359             elsif ( $is_double_consonant && $consonant eq 't' ) {
360 0           $translated_word .= $match_characters[2];
361             }
362             elsif ($is_double_consonant) {
363 0           $translated_word .= $match_characters[1];
364             }
365             else {
366 0           $translated_word .= $match_characters[0];
367             }
368             }
369              
370 0           return $translated_word;
371             }
372              
373             1;
374              
375             __END__