linguistics 1.0.9 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. data.tar.gz.sig +0 -0
  2. data/.gemtest +0 -0
  3. data/ChangeLog +849 -342
  4. data/History.rdoc +11 -0
  5. data/LICENSE +9 -9
  6. data/Manifest.txt +44 -0
  7. data/README.rdoc +226 -0
  8. data/Rakefile +32 -349
  9. data/examples/endocs.rb +272 -0
  10. data/examples/generalize_sentence.rb +2 -1
  11. data/examples/klingon.rb +22 -0
  12. data/lib/linguistics.rb +130 -292
  13. data/lib/linguistics/en.rb +337 -1628
  14. data/lib/linguistics/en/articles.rb +138 -0
  15. data/lib/linguistics/en/conjugation.rb +2245 -0
  16. data/lib/linguistics/en/conjunctions.rb +202 -0
  17. data/lib/linguistics/en/{infinitive.rb → infinitives.rb} +41 -55
  18. data/lib/linguistics/en/linkparser.rb +41 -49
  19. data/lib/linguistics/en/numbers.rb +483 -0
  20. data/lib/linguistics/en/participles.rb +33 -0
  21. data/lib/linguistics/en/pluralization.rb +810 -0
  22. data/lib/linguistics/en/stemmer.rb +75 -0
  23. data/lib/linguistics/en/titlecase.rb +121 -0
  24. data/lib/linguistics/en/wordnet.rb +63 -97
  25. data/lib/linguistics/inflector.rb +89 -0
  26. data/lib/linguistics/iso639.rb +534 -448
  27. data/lib/linguistics/languagebehavior.rb +36 -0
  28. data/lib/linguistics/monkeypatches.rb +42 -0
  29. data/spec/lib/constants.rb +15 -0
  30. data/spec/lib/helpers.rb +38 -0
  31. data/spec/linguistics/en/articles_spec.rb +797 -0
  32. data/spec/linguistics/en/conjugation_spec.rb +2083 -0
  33. data/spec/linguistics/en/conjunctions_spec.rb +154 -0
  34. data/spec/linguistics/en/infinitives_spec.rb +518 -0
  35. data/spec/linguistics/en/linkparser_spec.rb +66 -0
  36. data/spec/linguistics/en/numbers_spec.rb +1295 -0
  37. data/spec/linguistics/en/participles_spec.rb +55 -0
  38. data/spec/linguistics/en/pluralization_spec.rb +4636 -0
  39. data/spec/linguistics/en/stemmer_spec.rb +72 -0
  40. data/spec/linguistics/en/titlecase_spec.rb +841 -0
  41. data/spec/linguistics/en/wordnet_spec.rb +85 -0
  42. data/spec/linguistics/en_spec.rb +45 -167
  43. data/spec/linguistics/inflector_spec.rb +40 -0
  44. data/spec/linguistics/iso639_spec.rb +49 -53
  45. data/spec/linguistics/monkeypatches_spec.rb +40 -0
  46. data/spec/linguistics_spec.rb +46 -76
  47. metadata +241 -113
  48. metadata.gz.sig +0 -0
  49. data/README +0 -166
  50. data/README.english +0 -245
  51. data/rake/191_compat.rb +0 -26
  52. data/rake/dependencies.rb +0 -76
  53. data/rake/documentation.rb +0 -123
  54. data/rake/helpers.rb +0 -502
  55. data/rake/hg.rb +0 -318
  56. data/rake/manual.rb +0 -787
  57. data/rake/packaging.rb +0 -129
  58. data/rake/publishing.rb +0 -341
  59. data/rake/style.rb +0 -62
  60. data/rake/svn.rb +0 -668
  61. data/rake/testing.rb +0 -152
  62. data/rake/verifytask.rb +0 -64
  63. data/tests/en/infinitive.tests.rb +0 -207
  64. data/tests/en/inflect.tests.rb +0 -1389
  65. data/tests/en/lafcadio.tests.rb +0 -77
  66. data/tests/en/linkparser.tests.rb +0 -42
  67. data/tests/en/lprintf.tests.rb +0 -77
  68. data/tests/en/titlecase.tests.rb +0 -73
  69. data/tests/en/wordnet.tests.rb +0 -95
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'linguistics' unless defined?( Linguistics )
4
+ require 'linguistics/en' unless defined?( Linguistics::EN )
5
+
6
+ # Ruby-Stemmer support for the English-language Linguistics module. It
7
+ # requires the Ruby-Stemmer gem to be installed; if it is not
8
+ # installed, calling the functions defined by this file will raise
9
+ # NotImplementedErrors.
10
+ #
11
+ # # Test to be sure the Stemmer gem loaded okay.
12
+ # Linguistics::EN.has_stemmer?
13
+ # # => true
14
+ #
15
+ module Linguistics::EN::Stemmer
16
+
17
+ # Module instance variables -- copied over to the EN module when registered
18
+ @has_stemmer = false
19
+ @stemmer_error = nil
20
+ @stemmer = nil
21
+
22
+ # Load Ruby-Stemmer if possible, saving the error that occurs if anything goes wrong.
23
+ begin
24
+ require 'lingua/stemmer'
25
+ @has_stemmer = true
26
+ rescue LoadError => err
27
+ @stemmer_error = err
28
+ end
29
+
30
+
31
+ # Container for methods intended to extend the EN module as singleton methods.
32
+ module SingletonMethods
33
+
34
+ ### Returns +true+ if Ruby-Stemmer was loaded okay
35
+ def has_stemmer? ; @has_stemmer; end
36
+
37
+ ### If #has_stemmer? returns +false+, this can be called to fetch the
38
+ ### exception which was raised when Ruby-Stemmer was loaded.
39
+ def stemmer_error ; @stemmer_error; end
40
+
41
+ end # module SingletonMethods
42
+ extend SingletonMethods
43
+
44
+
45
+ # Register this module to the list of modules to include
46
+ Linguistics::EN.register_extension( self )
47
+
48
+ #################################################################
49
+ ### M O D U L E M E T H O D S
50
+ #################################################################
51
+
52
+ ### The instance of the Lingua::Stemmer used for all Linguistics Stemmer
53
+ ### functions.
54
+ def self::stemmer
55
+ raise self.stemmer_error unless self.has_stemmer?
56
+ @stemmer ||= Lingua::Stemmer.new
57
+ end
58
+
59
+
60
+ #################################################################
61
+ ### S T E M M E R I N T E R F A C E
62
+ #################################################################
63
+
64
+ ######
65
+ public
66
+ ######
67
+
68
+
69
+ ### Return the stem of the receiving word.
70
+ def stem
71
+ return Linguistics::EN::Stemmer.stemmer.stem( self.obj.to_s )
72
+ end
73
+
74
+ end # module Linguistics::EN::Stemmer
75
+
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'linguistics/en' unless defined?( Linguistics::EN )
4
+
5
+ # Methods for capitalizing a sentence as a title, nouns as proper
6
+ # nouns, and for turning a sentence into its equivalent CamelCaseSentence
7
+ # and vice-versa. It's part of the English-language Linguistics module.
8
+ module Linguistics::EN::TitleCase
9
+
10
+ # Register this module to the list of modules to include
11
+ Linguistics::EN.register_extension( self )
12
+
13
+
14
+ # Exceptions: Indefinite articles
15
+ ARTICLES = %w[a and the]
16
+
17
+ # Exceptions: Prepositions shorter than five letters
18
+ SHORT_PREPOSITIONS = ["amid", "at", "but", "by", "down", "for", "from", "in",
19
+ "into", "like", "near", "of", "off", "on", "onto", "out", "over",
20
+ "past", "save", "with", "till", "to", "unto", "up", "upon", "with"]
21
+
22
+ # Exceptions: Coordinating conjunctions
23
+ COORD_CONJUNCTIONS = %w[and but as]
24
+
25
+ # Titlecase exceptions: "In titles, capitalize the first word, the
26
+ # last word, and all words in between except articles (a, an, and
27
+ # the), prepositions under five letters (in, of, to), and coordinating
28
+ # conjunctions (and, but). These rules apply to titles of long, short,
29
+ # and partial works as well as your own papers" (Anson, Schwegler,
30
+ # and Muth. The Longman Writer's Companion 240).
31
+ TITLE_CASE_EXCEPTIONS = ARTICLES | SHORT_PREPOSITIONS | COORD_CONJUNCTIONS
32
+
33
+ # The words which don't get capitalized in a compound proper noun
34
+ PROPER_NOUN_EXCEPTIONS = %w{and the of}
35
+
36
+
37
+
38
+ ### Turns a camel-case +string+ ("camelCaseToEnglish") to plain English
39
+ ### ("camel case to english"). Each word is decapitalized.
40
+ def un_camel_case
41
+ self.to_s.
42
+ gsub( /([A-Z])([A-Z])/ ) { "#$1 #$2" }.
43
+ gsub( /([a-z])([A-Z])/ ) { "#$1 #$2" }.downcase
44
+ end
45
+
46
+
47
+ ### Turns an English language +string+ into a CamelCase word.
48
+ def to_camel_case
49
+ self.to_s.gsub( /\s+([a-z])/i ) { $1.upcase }
50
+ end
51
+
52
+
53
+ ### Returns the inflected object as a title-cased String.
54
+ ###
55
+ ### Some examples:
56
+ ###
57
+ ### "a portrait of the artist as a young man".en.titlecase
58
+ ### # => "A Portrait of the Artist as a Young Man"
59
+ ###
60
+ ### "a seven-sided romance".en.titlecase
61
+ ### # => "A Seven-Sided Romance"
62
+ ###
63
+ ### "the curious incident of the dog in the night-time".en.titlecase
64
+ ### # => "The Curious Incident of the Dog in the Night-Time"
65
+ ###
66
+ ### "the rats of n.i.m.h.".en.titlecase
67
+ ### # => "The Rats of N.I.M.H."
68
+ def titlecase
69
+
70
+ # Split on word-boundaries
71
+ words = self.to_s.split( /\b/ )
72
+
73
+ # Always capitalize the first and last words
74
+ words.first.capitalize!
75
+ words.last.capitalize!
76
+
77
+ # Now scan the rest of the tokens, skipping non-words and capitalization
78
+ # exceptions.
79
+ words.each_with_index do |word, i|
80
+
81
+ # Non-words
82
+ next unless /^\w+$/.match( word )
83
+
84
+ # Skip exception-words
85
+ next if TITLE_CASE_EXCEPTIONS.include?( word )
86
+
87
+ # Skip second parts of contractions
88
+ next if words[i - 1] == "'" && /\w/.match( words[i - 2] )
89
+
90
+ # Have to do it this way instead of capitalize! because that method
91
+ # also downcases all other letters.
92
+ word.gsub!( /^(\w)(.*)/ ) { $1.upcase + $2 }
93
+ end
94
+
95
+ return words.join
96
+ end
97
+
98
+
99
+ ### Returns the proper noun form of the inflected object by capitalizing most of the
100
+ ### words.
101
+ ###
102
+ ### Some examples:
103
+ ###
104
+ ### "bosnia and herzegovina".en.proper_noun
105
+ ### # => "Bosnia and Herzegovina"
106
+ ### "macedonia, the former yugoslav republic of".en.proper_noun
107
+ ### # => "Macedonia, the Former Yugoslav Republic of"
108
+ ### "virgin islands, u.s.".en.proper_noun
109
+ ### # => "Virgin Islands, U.S."
110
+ def proper_noun
111
+ return self.to_s.split(/([ .]+)/).collect do |word|
112
+ next word unless
113
+ /^[a-z]/.match( word ) &&
114
+ ! (PROPER_NOUN_EXCEPTIONS.include?( word ))
115
+ word.capitalize
116
+ end.join
117
+ end
118
+
119
+
120
+ end # module Linguistics::EN::TitleCase
121
+
@@ -1,61 +1,58 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- require 'linguistics/en'
3
+ require 'linguistics/en' unless defined?( Linguistics::EN )
4
4
 
5
- # This file contains functions for finding relations for English words. It
6
- # requires the Ruby-WordNet module to be installed; if it is not installed,
7
- # calling the functions defined by this file will raise NotImplemented
8
- # exceptions if called. Requiring this file adds functions and constants to the
9
- # Linguistics::EN module.
10
- #
11
- # == Synopsis
5
+ # WordNet support for the English-language Linguistics module. It
6
+ # requires the Ruby-WordNet module to be installed; if it is not
7
+ # installed, calling the functions defined by this file will raise
8
+ # NotImplementedErrors.
12
9
  #
13
10
  # # Test to be sure the WordNet module loaded okay.
14
11
  # Linguistics::EN.has_wordnet?
15
12
  # # => true
16
- #
13
+ #
17
14
  # # Fetch the default synset for the word "balance"
18
- # "balance".synset
15
+ # "balance".en.synset
19
16
  # # => #<WordNet::Synset:0x40376844 balance (noun): "a state of equilibrium"
20
17
  # (derivations: 3, antonyms: 1, hypernyms: 1, hyponyms: 3)>
21
- #
18
+ #
22
19
  # # Fetch the synset for the first verb sense of "balance"
23
20
  # "balance".en.synset( :verb )
24
21
  # # => #<WordNet::Synset:0x4033f448 balance, equilibrate, equilibrize, equilibrise
25
22
  # (verb): "bring into balance or equilibrium; "She has to balance work and her
26
23
  # domestic duties"; "balance the two weights"" (derivations: 7, antonyms: 1,
27
24
  # verbGroups: 2, hypernyms: 1, hyponyms: 5)>
28
- #
25
+ #
29
26
  # # Fetch the second noun sense
30
27
  # "balance".en.synset( 2, :noun )
31
28
  # # => #<WordNet::Synset:0x404ebb24 balance (noun): "a scale for weighing; depends
32
29
  # on pull of gravity" (hypernyms: 1, hyponyms: 5)>
33
- #
30
+ #
34
31
  # # Fetch the second noun sense's hypernyms (more-general words, like a superclass)
35
32
  # "balance".en.synset( 2, :noun ).hypernyms
36
33
  # # => [#<WordNet::Synset:0x404e5620 scale, weighing machine (noun): "a measuring
37
34
  # instrument for weighing; shows amount of mass" (derivations: 2, hypernyms: 1,
38
35
  # hyponyms: 2)>]
39
- #
36
+ #
40
37
  # # A simpler way of doing the same thing:
41
38
  # "balance".en.hypernyms( 2, :noun )
42
39
  # # => [#<WordNet::Synset:0x404e5620 scale, weighing machine (noun): "a measuring
43
40
  # instrument for weighing; shows amount of mass" (derivations: 2, hypernyms: 1,
44
41
  # hyponyms: 2)>]
45
- #
42
+ #
46
43
  # # Fetch the first hypernym's hypernyms
47
44
  # "balance".en.synset( 2, :noun ).hypernyms.first.hypernyms
48
45
  # # => [#<WordNet::Synset:0x404c60b8 measuring instrument, measuring system,
49
46
  # measuring device (noun): "instrument that shows the extent or amount or quantity
50
47
  # or degree of something" (hypernyms: 1, hyponyms: 83)>]
51
- #
48
+ #
52
49
  # # Find the synset to which both the second noun sense of "balance" and the
53
50
  # # default sense of "shovel" belong.
54
51
  # ("balance".en.synset( 2, :noun ) | "shovel".en.synset)
55
52
  # # => #<WordNet::Synset:0x40473da4 instrumentality, instrumentation (noun): "an
56
53
  # artifact (or system of artifacts) that is instrumental in accomplishing some
57
54
  # end" (derivations: 1, hypernyms: 1, hyponyms: 13)>
58
- #
55
+ #
59
56
  # # Fetch just the words for the other kinds of "instruments"
60
57
  # "instrument".en.hyponyms.collect {|synset| synset.words}.flatten
61
58
  # # => ["analyzer", "analyser", "cautery", "cauterant", "drafting instrument",
@@ -65,25 +62,13 @@ require 'linguistics/en'
65
62
  # instrument", "sonograph", "surveying instrument", "surveyor's instrument",
66
63
  # "tracer", "weapon", "arm", "weapon system", "whip"]
67
64
  #
68
- #
69
- # == Authors
70
- #
71
- # * Michael Granger <ged@FaerieMUD.org>
72
- #
73
- # :include: LICENSE
74
- #
75
- # == Version
76
- #
77
- # $Id: wordnet.rb,v 2640c845eb5c 2009/11/17 16:59:25 ged $
78
- #
79
- module Linguistics::EN
65
+ module Linguistics::EN::WordNet
80
66
 
81
- @has_wordnet = false
82
- @wn_error = nil
83
- @wn_lexicon = nil
67
+ @has_wordnet = false
68
+ @wn_error = nil
69
+ @lexicon = nil
84
70
 
85
- # Load WordNet and open the lexicon if possible, saving the error that
86
- # occurs if anything goes wrong.
71
+ # Load WordNet if possible, saving the error that occurs if anything goes wrong.
87
72
  begin
88
73
  require 'wordnet'
89
74
  @has_wordnet = true
@@ -92,44 +77,48 @@ module Linguistics::EN
92
77
  end
93
78
 
94
79
 
95
- #################################################################
96
- ### M O D U L E M E T H O D S
97
- #################################################################
98
- class << self
80
+ # Container for methods intended to extend the EN module as singleton methods.
81
+ module SingletonMethods
99
82
 
100
83
  ### Returns +true+ if WordNet was loaded okay
101
84
  def has_wordnet? ; @has_wordnet; end
102
85
 
103
- ### If #haveWordnet? returns +false+, this can be called to fetch the
86
+ ### If #has_wordnet? returns +false+, this can be called to fetch the
104
87
  ### exception which was raised when WordNet was loaded.
105
- def wn_error ; @wn_error; end
106
-
107
- ### The instance of the WordNet::Lexicon used for all Linguistics WordNet
108
- ### functions.
109
- def wn_lexicon
110
- if @wn_error
111
- raise NotImplementedError,
112
- "WordNet functions are not loaded: %s" %
113
- @wn_error.message
114
- end
115
-
116
- @wn_lexicon ||= WordNet::Lexicon::new
117
- end
88
+ def wordnet_error ; @wn_error; end
89
+
90
+ end # module SingletonMethods
91
+ extend SingletonMethods
118
92
 
119
- ### Make a function that calls the method +meth+ on the synset of an input
120
- ### word.
121
- def def_synset_function( meth )
122
- (class << self; self; end).instance_eval do
123
- define_method( meth ) {|*args|
124
- word, pos, sense = *args
125
- raise ArgumentError,
126
- "wrong number of arguments (0 for 1)" unless word
127
- sense ||= 1
128
-
129
- syn = synset( word.to_s, pos, sense )
130
- return syn.nil? ? nil : syn.send( meth )
131
- }
132
- end
93
+
94
+ # Register this module to the list of modules to include
95
+ Linguistics::EN.register_extension( self )
96
+
97
+
98
+ #################################################################
99
+ ### M O D U L E M E T H O D S
100
+ #################################################################
101
+
102
+ ### The instance of the WordNet::Lexicon used for all Linguistics WordNet
103
+ ### functions.
104
+ def self::lexicon
105
+ raise self.wordnet_error unless self.has_wordnet?
106
+ @lexicon ||= WordNet::Lexicon::new
107
+ end
108
+
109
+
110
+ ### Set the WordNet::Lexicon used by the linguistic functions.
111
+ def self::lexicon=( newlex )
112
+ @lexicon = newlex
113
+ end
114
+
115
+
116
+ ### Make a function that calls the method +meth+ on the synset of an input
117
+ ### word.
118
+ def self::def_synset_function( name )
119
+ define_method( name ) do |*criteria|
120
+ syn = self.synset( *criteria ) or return nil
121
+ return syn.send( name )
133
122
  end
134
123
  end
135
124
 
@@ -139,50 +128,27 @@ module Linguistics::EN
139
128
  ### W O R D N E T I N T E R F A C E
140
129
  #################################################################
141
130
 
142
- ###############
143
- module_function
144
- ###############
131
+ ######
132
+ public
133
+ ######
145
134
 
146
135
  ### Look up the synset associated with the given word or collocation in the
147
136
  ### WordNet lexicon and return a WordNet::Synset object.
148
- def synset( word, pos=nil, sense=1 )
149
- lex = Linguistics::EN::wn_lexicon
150
- if pos.is_a?( Fixnum )
151
- sense = pos
152
- pos = nil
153
- end
154
- postries = pos ? [pos] : [:noun, :verb, :adjective, :adverb, :other]
155
- syn = nil
156
-
157
- postries.each do |pos|
158
- break if syn = lex.lookup_synsets( word.to_s, pos, sense )
159
- end
160
-
161
- return syn
137
+ def synset( *args )
138
+ return Linguistics::EN::WordNet.lexicon[ self.to_s, *args ]
162
139
  end
163
140
 
164
141
 
165
142
  ### Look up all the synsets associated with the given word or collocation in
166
143
  ### the WordNet lexicon and return an Array of WordNet::Synset objects. If
167
144
  ### +pos+ is +nil+, return synsets for all parts of speech.
168
- def synsets( word, pos=nil )
169
- lex = Linguistics::EN::wn_lexicon
170
- postries = pos ? [pos] : [:noun, :verb, :adjective, :adverb, :other]
171
- syns = []
172
-
173
- postries.each {|pos|
174
- syns << lex.lookup_synsets( word.to_s, pos )
175
- }
176
-
177
- return syns.flatten.compact
145
+ def synsets( *args )
146
+ return Linguistics::EN::WordNet.lexicon.lookup_synsets( self.to_s, *args )
178
147
  end
179
148
 
180
149
 
181
150
  # Returns definitions and/or example sentences as a String.
182
- def_synset_function :gloss
183
-
184
- # Returns definitions and/or example sentences as an Array.
185
- def_synset_function :glosses
151
+ def_synset_function :definition
186
152
 
187
153
  # Return nouns or verbs that have the same hypernym as the receiver.
188
154
  def_synset_function :coordinates
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/ruby
2
+ # coding: utf-8
3
+
4
+ require 'loggability'
5
+ require 'linguistics' unless defined?( Linguistics )
6
+
7
+ # A facade object that acts as the extension point for linguistic modules
8
+ # for a single language. A single instance of an inflector is generated
9
+ # for an object that has been extended with a Linguistics language
10
+ # the first time the language is used.
11
+ class Linguistics::Inflector
12
+ extend Loggability
13
+
14
+
15
+ # Loggability API -- log to the linguistics logger
16
+ log_to :linguistics
17
+
18
+
19
+ ### Create a new inflector for +obj+.
20
+ def initialize( language_code, obj )
21
+ raise TypeError, "can't inflect for another inflector!" if
22
+ obj.is_a?( Linguistics::Inflector )
23
+ @language_code = language_code
24
+ @obj = obj
25
+ super()
26
+ end
27
+
28
+
29
+ ######
30
+ public
31
+ ######
32
+
33
+ # The object the inflector is delegating for
34
+ attr_reader :obj
35
+
36
+ # The inflector's language code
37
+ attr_reader :language_code
38
+
39
+
40
+ ### Return the english-language name of the language the inflector is delegating
41
+ ### for.
42
+ def language
43
+ ::Linguistics::ISO639::LANGUAGE_CODES[ self.language_code.to_sym ][:eng_name]
44
+ end
45
+
46
+
47
+ ### Returns +true+ if either the inflector or the object it's wrapping respond to
48
+ ### the specified +message+.
49
+ def respond_to_missing?( message, include_priv=false )
50
+ return self.obj.respond_to?( message, include_priv )
51
+ end
52
+
53
+
54
+ ### Return the target object as a String.
55
+ def to_s
56
+ return self.obj.to_s
57
+ end
58
+
59
+
60
+ ### Return the target object as an Integer
61
+ def to_i
62
+ return self.obj.to_i
63
+ end
64
+
65
+
66
+ ### Output a programmer-readable representation of the object suitable for debugging.
67
+ def inspect
68
+ return "#<(%s-language inflector) for <%s:0x%0x> >" % [
69
+ self.language,
70
+ @obj.class,
71
+ @obj.object_id / 2
72
+ ]
73
+ end
74
+
75
+
76
+ #########
77
+ protected
78
+ #########
79
+
80
+ ### Delegate missing methods to the target object.
81
+ def method_missing( sym, *args, &block )
82
+ return super unless self.obj.respond_to?( sym )
83
+ meth = self.obj.method( sym )
84
+ self.singleton_class.send( :define_method, sym, &meth )
85
+ return self.method( sym ).call( *args, &block )
86
+ end
87
+
88
+ end # class Linguistics::Inflector
89
+