latinverb 0.2.0 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.gitignore +0 -1
  2. data/Gemfile +1 -2
  3. data/README.markdown +54 -240
  4. data/etc/irreg_skel.json +104 -0
  5. data/{latinirb.gemspec → latinverb.gemspec} +4 -4
  6. data/lib/latinverb/chart.rb +94 -0
  7. data/lib/latinverb/version.rb +10 -0
  8. data/lib/latinverb.rb +710 -0
  9. data/lib/linguistics/latin/verb/classification_types.rb +59 -0
  10. data/lib/linguistics/latin/verb/constants.rb +201 -0
  11. data/lib/linguistics/latin/verb/deponent_tense_methods.rb +98 -0
  12. data/lib/linguistics/latin/verb/infinitives.rb +212 -0
  13. data/lib/linguistics/latin/verb/irregulars.rb +4393 -0
  14. data/lib/linguistics/latin/verb/latinverb/auxiliary_classes.rb +208 -0
  15. data/lib/linguistics/latin/verb/latinverb/classmethods.rb +215 -0
  16. data/lib/linguistics/latin/verb/latinverb/data.rb +90 -0
  17. data/lib/linguistics/latin/verb/latinverb/display.rb +23 -0
  18. data/lib/linguistics/latin/verb/latinverb/metaprogramming.rb +79 -0
  19. data/lib/linguistics/latin/verb/latinverb/validation.rb +66 -0
  20. data/lib/linguistics/latin/verb/participles.rb +202 -0
  21. data/lib/linguistics/latin/verb/phonographia.rb +109 -0
  22. data/lib/linguistics/latin/verb/supine.rb +42 -0
  23. data/lib/linguistics/latin/verb/tense_methods.rb +950 -0
  24. data/test/testAmbiguousLookups.rb +30 -0
  25. data/test/testClusterResolution.rb +20 -0
  26. data/test/testDataStructures.rb +29 -0
  27. data/test/testDefectSemiImp.rb +111 -0
  28. data/test/testDeponentFirstConjugation.rb +64 -0
  29. data/test/testDeponentFourthConjugation.rb +64 -0
  30. data/test/testDeponentSecondConjugation.rb +64 -0
  31. data/test/testDeponentThirdConjugation.rb +64 -0
  32. data/test/testDeponentThirdIOConjugation.rb +64 -0
  33. data/test/testDeserializeInfinitives.rb +38 -0
  34. data/test/testFirstConjugation.rb +388 -0
  35. data/test/testFourthConjugation.rb +190 -0
  36. data/test/testFreakishVerbs.rb +93 -0
  37. data/test/testImperativeBlock.rb +27 -0
  38. data/test/testIrregularSum.rb +22 -0
  39. data/test/testIrregulars.rb +652 -0
  40. data/test/testLatinVerb.rb +195 -0
  41. data/test/testMacronRules.rb +19 -0
  42. data/test/testSecondConjugation.rb +189 -0
  43. data/test/testThirdConjugation.rb +190 -0
  44. data/test/testThirdIOConjugation.rb +190 -0
  45. metadata +70 -18
  46. data/bin/latinirb.rb +0 -7
  47. data/latinverb.rb +0 -544
  48. data/lib/LatinIRB.rb +0 -172
  49. data/lib/latinirb/paradigmatic_verbs.rb +0 -17
  50. data/lib/latinirb/version.rb +0 -10
  51. data/lib/latirb.rb +0 -20
@@ -0,0 +1,208 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'linguistics/latin/verb/phonographia'
4
+ require 'yaml'
5
+
6
+ module Linguistics
7
+ module Latin
8
+ module Verb
9
+
10
+ class ParticipleBlock
11
+ attr_reader :participle_methods
12
+
13
+
14
+ def initialize(s)
15
+ raise "ParticipleBlock instantiation argument was nil!" if s.nil?
16
+
17
+ if s.class == Hash
18
+ @participle_methods = s.keys
19
+ end
20
+
21
+ @participle_methods.each do |k|
22
+ v=s[k]
23
+ singleton_class.class_eval do
24
+ define_method k.to_sym do
25
+ return v
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ ##
32
+ #
33
+ # Required for deserialization
34
+ #
35
+ ##
36
+ def self.json_create(o)
37
+ new(o['data'])
38
+ end
39
+ end
40
+
41
+
42
+ #-------------------------------------------------------------------------------
43
+ #-------------------------------------------------------------------------------
44
+ ##
45
+ #
46
+ # The InfinitiveBlock holds the infinitives associated with a given
47
+ # verb. The known infinitives are the following:
48
+ #
49
+ # *
50
+ class InfinitiveBlock
51
+ attr_reader :infinitive_methods
52
+ def initialize(s)
53
+ if s.class == Hash
54
+ @infinitive_methods = s.keys
55
+ end
56
+
57
+ @infinitive_methods.each do |k|
58
+ v=s[k]
59
+ singleton_class.class_eval do
60
+ define_method k.to_sym do
61
+ return v
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ ##
68
+ #
69
+ # Required for deserialization
70
+ #
71
+ ##
72
+ def self.json_create(o)
73
+ new(o['data'])
74
+ end
75
+ end
76
+
77
+ class ImperativeBlock
78
+ def initialize(stem,ppi)
79
+ # In case we get an Array, for JSON revivification
80
+ if stem.class == Array
81
+ @results = stem
82
+ end
83
+
84
+ r = case
85
+ when ppi =~ /āre$/
86
+ [stem, stem+"te"]
87
+ when ppi =~ /ēre$/
88
+ [stem, stem+"te"]
89
+ when ppi =~ /ere$/
90
+ [stem+"e", stem+"ite"]
91
+ when ppi =~ /īre$/
92
+ [stem+"ī", stem+"īte"]
93
+ end
94
+
95
+ r << stem + "tō"
96
+ r << stem + "tōte"
97
+
98
+ r << stem + "tō"
99
+ r << stem + "ntō"
100
+
101
+ @results = r.map{|v| Linguistics::Latin::Phonographia.fix_macrons v}
102
+ end
103
+
104
+ def to_s
105
+ return @results
106
+ end
107
+
108
+ ##
109
+ #
110
+ # Required for serialization
111
+ #
112
+ ##
113
+ def to_json(*a)
114
+ {
115
+ 'json_class' => self.class.name,
116
+ 'data' => @results.map{|i| i.to_json}
117
+ }.to_json(*a)
118
+ end
119
+
120
+ ##
121
+ #
122
+ # Required for deserialization
123
+ #
124
+ ##
125
+ def self.json_create(o)
126
+ new(o['data'])
127
+ end
128
+
129
+ ##
130
+ #
131
+ # Provides Array-like interface to the collection of results.
132
+ #
133
+ ##
134
+ def [](arg)
135
+ @results[arg]
136
+ end
137
+
138
+ ##
139
+ #
140
+ # To Array, useful in serialization
141
+ #
142
+ ##
143
+ def to_a
144
+ return @results
145
+ end
146
+
147
+ ##
148
+ #
149
+ # Add array compatibility support
150
+ #
151
+ ##
152
+ def length; return @results.length; end
153
+
154
+ ##
155
+ #
156
+ # Returns the two, second person imperatives
157
+ #
158
+ ##
159
+ def present(qualifier=nil)
160
+ j=@results[0,2]
161
+ return j if qualifier.nil?
162
+ qualifier = qualifier.to_s
163
+ return j[0] if qualifier =~ /singular/
164
+ return j[1] if qualifier =~ /plural/
165
+ end
166
+
167
+ ##
168
+ #
169
+ # Returns the four, second and third person future imperatives
170
+ #
171
+ ##
172
+ def future(qualifier=nil)
173
+ return j=@results[2,4] if qualifier.nil?
174
+
175
+ # case
176
+ # when qualifier =~ /second_person/
177
+ # if qualifier =~ /singular/
178
+ # return j[0]
179
+ # elsif qualifier =~ /plural/
180
+ # return j[2]
181
+ # else
182
+ # return [ j[0], j[2] ]
183
+ # end
184
+ # when qualifier =~ /third_person/
185
+ # if qualifier =~ /singular/
186
+ # return j[1]
187
+ # elsif qualifier =~ /plural/
188
+ # return j[3]
189
+ # else
190
+ # return [ j[1], j[3] ]
191
+ # end
192
+ # else
193
+ # raise "[future] could not parse this imperative"
194
+ # end
195
+ # end
196
+ end
197
+
198
+ def method_missing(sym,*args)
199
+ if (sym =~ /^(present|future)_tense_(.*)/)
200
+ self.send($1.to_sym, $2)
201
+ else
202
+ super
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end
208
+ end
@@ -0,0 +1,215 @@
1
+ # encoding: UTF-8
2
+
3
+ module Linguistics
4
+ module Latin
5
+ module Verb
6
+ class LatinVerb
7
+
8
+ class << self
9
+
10
+ ##
11
+ #
12
+ # Deponent verbs can be conceived as being the <em>the passive</em> results of
13
+ # a regular verb where the passive form's result is then applied to the active
14
+ # vector specification. Ergo the dictum "passive in form but active in
15
+ # meaning." As such, when we realize we have a deponent verb, we will create
16
+ # its standard four principal part string sibling. This, in turn, could be
17
+ # used to create a LatinVerb. Then through some method deletion or aliasing,
18
+ # the active vector can be used to point to the (in fact) passive result
19
+ #
20
+ # For example:
21
+ #
22
+ # <pre>
23
+ # j = LatinVerb.new conor conārī conatus
24
+ # # create_pseudo_active_mask_for_deponent creates (conō, conāre, conāvī
25
+ # conatus)
26
+ # # Do magic so that active_voice_indicative_mood_present_tense points to
27
+ # passive_voice_indicative_mood_present_tense
28
+ # </pre>
29
+ #
30
+ # ===ARGUMENTS
31
+ #
32
+ # s :: A deponent description string to be pesudo-mapped
33
+ #
34
+ # ===RETURNS
35
+ #
36
+ # A pseudo-mapped, four principal-part string
37
+ #
38
+ ##
39
+ def create_pseudo_active_mask_for_deponent(s)
40
+ parts = s.split /\s+/
41
+
42
+ # Turn the passive form into something that looks active
43
+ parts[0].sub! /or$/, 'ō'
44
+
45
+ # Turn the passive infinitive into something that looks active.
46
+ # There's a subtle difference between:
47
+ # 'vereor verērī veritum'
48
+ # 'sequor sequī secūtus'
49
+ # Applying the first's rule to the second results in 'seque' not
50
+ # 'sequere'. Ergo the conditional.
51
+ #
52
+ parts[1].sub! /ī$/, 'e'
53
+
54
+ # Fixes sequī -> sequere
55
+ parts[1] += 're' unless parts[1] =~ /[āīē]re/
56
+
57
+ # Set the 4th part to the value in the 3rd slot
58
+ parts[3] = parts[2]
59
+
60
+ # Another modification for third conjugation deponents
61
+ parts[3].sub! /us$/, 'um'
62
+
63
+ # This value shouldn't be used...(I don't think...)
64
+ parts[2] = "JUNK" #
65
+
66
+ parts.join(' ')
67
+ end
68
+ ##
69
+ #
70
+ # == ARGUMENTS
71
+ #
72
+ # * s :: a "four principal parts" string whence can be derived
73
+ # the first person singular present indicative as well as the
74
+ # infinitive
75
+ #
76
+ # == RETURNS
77
+ #
78
+ # The classification, a subclass of VerbType
79
+ #
80
+ # == PURPOSE
81
+ #
82
+ # Given the principal parts as a string, decide which conjuation is
83
+ # in play
84
+ #
85
+ #
86
+ ##
87
+ def classify(s)
88
+
89
+ if s.class == String
90
+ divided_string = s.split /\s+/
91
+
92
+ first_pres = divided_string[0]
93
+ infinitive = divided_string[1]
94
+
95
+ return Linguistics::Latin::Verb::VerbTypes::Defective if
96
+ Linguistics::Latin::Verb::LatinVerb::DEFECTIVE_VERBS.member? first_pres
97
+
98
+ return Linguistics::Latin::Verb::VerbTypes::Irregular if
99
+ Linguistics::Latin::Verb::LatinVerb::IRREGULAR_VERBS.member? first_pres
100
+
101
+ return Linguistics::Latin::Verb::VerbTypes::Semideponent if
102
+ ( Linguistics::Latin::Verb::LatinVerb::SEMI_DEPONENTS.keys.any?{ |k| first_pres=~/#{k}$/} and
103
+ s !~ /JUNK/ )
104
+
105
+ return Linguistics::Latin::Verb::VerbTypes::Impersonal if
106
+ Linguistics::Latin::Verb::LatinVerb::IMPERSONAL_VERBS.member? s
107
+
108
+ if infinitive =~ /āre$/
109
+ return Linguistics::Latin::Verb::VerbTypes::First
110
+ elsif infinitive =~ /ēre$/
111
+ return Linguistics::Latin::Verb::VerbTypes::Second
112
+ elsif infinitive =~ /ere$/
113
+ if first_pres =~ /i.$/
114
+ return Linguistics::Latin::Verb::VerbTypes::ThirdIO
115
+ else
116
+ return Linguistics::Latin::Verb::VerbTypes::Third
117
+ end
118
+ elsif infinitive =~ /.+īre$/
119
+ return Linguistics::Latin::Verb::VerbTypes::Fourth
120
+ elsif (infinitive =~ /ī$/ and first_pres =~ /r$/)
121
+ return Linguistics::Latin::Verb::VerbTypes::Deponent
122
+ # Very irregular irregulars, A&G206, e/f
123
+ elsif s =~ %r'^(aiō|quaesō|ovāre)$'
124
+ return Linguistics::Latin::Verb::VerbTypes::Irregular
125
+ else
126
+ raise "Could not find a verb type for this verb #{infinitive} and #{first_pres}"
127
+ end
128
+ end
129
+ end
130
+
131
+ ##
132
+ #
133
+ # == ARGUMENTS
134
+ #
135
+ # * pres_act_inf
136
+ #
137
+ # == RETURNS
138
+ #
139
+ # The “stem” of a Latin Verb
140
+ #
141
+ # == PURPOSE
142
+ #
143
+ # Based on the present active infinitive, identify the “stem” and set the +@stem+
144
+ # iVar. The method also returns the stem value.
145
+ #
146
+ ##
147
+ def calculate_stem(pres_act_inf)
148
+ # TODO: For efficiency, if the iVar @stem is defined, don't go through this structure?
149
+ if pres_act_inf =~ /āre$/
150
+ return pres_act_inf.gsub(/(.*)āre$/,'\\1ā')
151
+ end
152
+ if pres_act_inf =~ /ēre$/
153
+ return pres_act_inf.gsub(/(.*)ēre$/,'\\1ē')
154
+ end
155
+ if pres_act_inf =~ /ere$/
156
+ if @first_pers_singular =~ /iō$/
157
+ return pres_act_inf.gsub(/(.*)ere$/,'\\1')
158
+ else
159
+ return pres_act_inf.gsub(/(.*)ere$/,'\\1')
160
+ end
161
+ end
162
+ if pres_act_inf =~ /īre$/
163
+ return pres_act_inf.gsub(/(.*)īre$/,'\\1')
164
+ end
165
+ end
166
+
167
+ ##
168
+ #
169
+ # == ARGUMENTS
170
+ #
171
+ # * first_person_singular
172
+ # * pres_act_inf
173
+ #
174
+ # == RETURNS
175
+ #
176
+ # The participial “stem” of a Latin Verb, used for participle
177
+ # formation
178
+ #
179
+ # == PURPOSE
180
+ #
181
+ # Calculate the participial stem, used in forming participles.
182
+ #
183
+ ##
184
+ def calculate_participial_stem(first_pers_singular, pres_act_inf)
185
+ raise("pres_act_inf was nil![#{first_pers_singular} and #{pres_act_inf}]") if
186
+ pres_act_inf.empty? or first_pers_singular.empty?
187
+
188
+ if pres_act_inf.to_s =~ /(.*ā)re$/
189
+ return $1
190
+ end
191
+
192
+ if pres_act_inf.to_s =~ /(.*ē)re$/
193
+ return $1
194
+ end
195
+
196
+ if pres_act_inf.to_s =~ /(.*)ere$/
197
+ match=$1
198
+ if first_pers_singular =~ /iō/
199
+ return match + "iē"
200
+ else
201
+ return match + "e"
202
+ end
203
+ end
204
+
205
+ if pres_act_inf.to_s =~ /(.*)īre$/
206
+ return $1 + "iē"
207
+ end
208
+ end
209
+
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
215
+
@@ -0,0 +1,90 @@
1
+ # encoding: UTF-8
2
+ require 'json'
3
+
4
+ module Linguistics
5
+ module Latin
6
+ module Verb
7
+ class LatinVerb
8
+ ##
9
+ #
10
+ # Required method for JSON deserialization
11
+ #
12
+ ##
13
+ def self.json_create(o)
14
+ new( o )
15
+ end
16
+
17
+ ##
18
+ #
19
+ # Presents the LatinVerb expressed as a hash with the names of the TenseBlock
20
+ # specifiers as keys, and corresponding TenseBlock objects, converted to
21
+ # Arrays, as the values. It also contains the +original_string+.
22
+ #
23
+ ##
24
+ def to_hash
25
+ @tense_list.each do |t|
26
+ ts = t.to_sym
27
+ @data_structure[ts]=self.send ts
28
+ end
29
+ @data_structure['original_string'] = @original_string
30
+ return @data_structure
31
+ end
32
+
33
+ alias_method :to_h, :to_hash
34
+
35
+ ##
36
+ #
37
+ # Takes the hash that results from to_hash and then converts it to
38
+ # YAML.
39
+ #
40
+ ##
41
+ def to_yaml
42
+ @data_structure.empty? ?
43
+ to_hash.to_yaml:
44
+ @data_structure.to_yaml
45
+ end
46
+
47
+ alias_method :to_y, :to_yaml
48
+
49
+ ##
50
+ #
51
+ # Required method for JSON deserialization
52
+ #
53
+ ##
54
+ def to_json(*a)
55
+ json_hash = {'json_class' => self.class.name}
56
+
57
+ # In the case that we're working with a regular verb, the only thing
58
+ # we need to save is the original string, since everything can be
59
+ # re-derived from it easily.
60
+ unless self.irregular?
61
+ # While this single string is sufficient to freeze and revivifty
62
+ # the verb, it means that the JSON structure is rather vacuous.
63
+ # Given this, the hash is enriched so that the JSON data is
64
+ # useful. Nevertheless, in the revivification process, only
65
+ # 'orig_string' is used.
66
+ %w{original_string classification stem}.each do |k|
67
+ json_hash[k] = self.send k.to_sym
68
+ end
69
+ json_hash['tense_list' ] = {}
70
+ @tense_list.each do |t|
71
+ json_hash['tense_list'][t.to_s] = self.send t.to_sym
72
+ end
73
+ json_hash['irregular'] = irregular?
74
+ return json_hash.to_json(*a)
75
+ end
76
+ end
77
+
78
+ ##
79
+ #
80
+ # Dumps the LatinVerb as pretty JSON
81
+ #
82
+ ##
83
+ def pretty_generate
84
+ JSON.pretty_generate(@data_structure.keys.length < 1 ? to_hash : @data_structure)
85
+ end
86
+
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: UTF-8
2
+ module Linguistics
3
+ module Latin
4
+ module Verb
5
+ class LatinVerb
6
+
7
+ ##
8
+ #
9
+ # <b>You should not be using this, probably</b>
10
+ #
11
+ # This is a a convenience method so that you can print out the
12
+ # contents in a human-readable fashion. LatinVerb is a library that
13
+ # _should be implemented elsewhere_ where its results can be presented
14
+ # by more view-oriented libraries or applications.
15
+ ##
16
+ def display
17
+ STDERR.puts "You should not be going much displaying here as this is a LIBRARY. Implement this elsewhere."
18
+ pretty_generate
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,79 @@
1
+ # encoding: UTF-8
2
+
3
+ =begin rdoc
4
+ #--
5
+ # The purpose of this module is to contain the metaprogramming modules
6
+ # method_missing and respond_to? in a place that's nice and neat.
7
+ # ++
8
+ =end
9
+
10
+ module Linguistics
11
+ module Latin
12
+ module Verb
13
+ class LatinVerb
14
+
15
+ =begin rdoc
16
+
17
+ === DESCRIPTION
18
+
19
+ Override of the method_missing method. A lot of the magic of LatinVerb
20
+ happens here. This method has deep interactoion with the Verbvector results
21
+ called as part of the LatinVerb.initialize call path.
22
+
23
+ === INTERNALS
24
+
25
+ Given a symbol that is undefined, we look to +@tense_list+ first. The typical
26
+ case would be a call on a 3/5ths vector identification. Therefore if the call
27
+ is pure nonsense, the symbol will not be found on the first evaluation and go
28
+ to super. Assuming that the symbol IS a partial vector call, it will match
29
+ through the iteration of the values in +@tense_list+. Based on the match, two
30
+ Regexp values are derived:
31
+
32
+ * the first 3/5ths (enough to get a TenseBlock), called a +tense_method+
33
+ * the last 2/5ths (enough to specify a value out of that TenseBlock), called a +vector_specifier+
34
+
35
+ Given those two names, the tense_method is called on the LatinVerb with +send+
36
+ and _that_ resultant value, a TenseBlock, undergoes a +send+ call to the
37
+ specifier, thus all 5/5 components of the fully-qualified vector can result in
38
+ unique match.
39
+
40
+ =end
41
+ def method_missing(symbol, *args ) # :nodoc:
42
+ super if @tense_list.nil?
43
+ @tense_list.find do |e|
44
+ if symbol.to_s.match /^(#{e})_(.*)/
45
+ tense_method, vector_specifier = $1, $2
46
+ # This is added to prevent stack-level too deep errors
47
+ begin
48
+ # Handle the base case
49
+ if self.respond_to?(tense_method.to_sym)
50
+ return send(tense_method.to_sym).send(vector_specifier.to_sym)
51
+ end
52
+ rescue SystemStackError => e
53
+ STDERR.puts "We encountered a SystemStackError when calling #{tense_method}"
54
+ STDERR.puts "WARNING: Failed to resolve [#{tense_method}] with [#{vector_specifier}]. \n\nMake sure #{tense_method} is defined."
55
+ super
56
+ end
57
+ end
58
+ end
59
+ super
60
+ end
61
+
62
+ ##
63
+ #
64
+ # We override respond_to so that we respond to the normal object
65
+ # models as well as accept the method_missing utilized names as well.
66
+ # If it's in +respondable_methods+, we return true.
67
+ #
68
+ ##
69
+ def respond_to?(symbol, include_private=false)
70
+ super if respondable_methods.nil?
71
+ super if respondable_methods.empty?
72
+ self.respondable_methods.grep(Regexp.new %Q/^#{symbol}$/).empty? ?
73
+ super : true
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+
@@ -0,0 +1,66 @@
1
+ # encoding: UTF-8
2
+
3
+ module Linguistics
4
+ module Latin
5
+ module Verb
6
+ ##
7
+ # == NAME
8
+ #
9
+ # Validation
10
+ #
11
+ # == DESCRIPTION
12
+ #
13
+ # This module contains the validity testing methods, when mixed into a
14
+ # LatinVerb, will provide it the ability to ensure its own sanity.
15
+ #
16
+ ##
17
+ module Validation
18
+
19
+ ##
20
+ #
21
+ # == DESCRIPTION
22
+ #
23
+ # This performs the basic task of evaluating the given string (cf.
24
+ # LatinVerb.initialize) for basic sanity.
25
+ #
26
+ # Here are its basic truths
27
+ #
28
+ # 1. Get +@original_string+ as an iVar
29
+ # 1. Derive a classification (+@classification+) from the string
30
+ # 1. Determine whether the string qualifies the verb as irregular
31
+ # 1. Identify a stem (+@stem+), provided the verb is regular
32
+ #
33
+ ##
34
+ def valid?
35
+ os = @original_string
36
+ instance_eval do
37
+ begin
38
+ @classification = Linguistics::Latin::Verb::LatinVerb.classify(os)
39
+ @irregular =
40
+ @classification == Linguistics::Latin::Verb::VerbTypes::Irregular ?
41
+ true : false
42
+ unless @irregular
43
+ @stem ||= self.class.calculate_stem os.split(/\s+/)[1]
44
+ @deponent = (@classification == Linguistics::Latin::Verb::VerbTypes::Deponent) ?
45
+ true : false
46
+ @semideponent = (@classification == Linguistics::Latin::Verb::VerbTypes::Semideponent) ?
47
+ true : false
48
+ @impersonal= (@classification == Linguistics::Latin::Verb::VerbTypes::Impersonal) ?
49
+ true : false
50
+ end
51
+ rescue RuntimeError => detail
52
+ STDERR.puts "WARNING: Improper use of rescue for decision structure in latinverb_validation"
53
+ @irregular = true
54
+ rescue Exception => e
55
+ @classification_error = lambda do
56
+ raise e
57
+ end
58
+ end
59
+ end
60
+ return true
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+