[Ruby][Latin] Forget how to construct your passive voice indicative verbs in Latin? Ruby to rescue.


This started off as a bit of an amusement just to see if i could show the elegance of Ruby – and find a way to help me memorize the suffix-addition-heuristics that characterize inflected languages like Latin.

As usual, it quickly became much more than that.

Known Issue:

The macrons are slightly off, particularly in the 3rd person plural ( no vowel before ’nt’ should ever be lengthened ). I’ll write a fixer routine soon.

[code lang="ruby"]
#!/usr/bin/env ruby
class Verb < Object
  attr_reader :firstpersonform, :infinitive, 
              :perfectstem, :passperfpart, :stem
  def initialize(initString)
    (@firstpersonform, @infinitive, 
	   @perfectstem, @passperfpart)=initString.split(/,\s+/)
    @passive_endings = ["r", "ris", "tur", 
                        "mur", "min\xc4\xab", "ntur"]
    @personages = ["First Singular", "Second Singular", 
                   "Third Singular",
                   "First Plural", "Second Plural", "Third Plural"]
  def stem
    # For efficiency, if the iVar @stem is defined, don't go 
    # through this structure
    return @stem unless @stem.nil?
    if @infinitive =~ /?re$/
      return @stem = @infinitive.gsub(/(.*)?re$/,'\\1?')
    if @infinitive =~ /?re$/
      return @stem = @infinitive.gsub(/(.*)?re$/,'\\1?')
  def to_s
    return "#{self.firstpersonform} #{self.infinitive} 
       #{self.perfectstem} #{self.passperfpart}"
  def present_passive
    return [@firstpersonform + "r", 
      local_pe[1..-1].map{|x| self.stem + x}].flatten!
  def imperfect_passive
    imperfect_stem = self.stem + "b\xc4\x81"
    return{|x| "#{imperfect_stem}#{x}"}
  def future_passive
    standards = @passive_endings[2..-1].map{|x| fp_stem + x}
    return [@stem + "b\xc5\x8d", @stem + "beris", standards].flatten!
  def passive_system
    p_sys_hash= { :label=>@personages,
                  :present => self.present_passive,
                  :imperfect => self.imperfect_passive,
                  :future => self.future_passive}
    0.upto(5) do |index|
      printf("%-15s %-10s %-16s %s\n", 
    puts "\n\n"
[/code]"laudō, laudāre, laudāvī, laudatus")
	puts x
	x.passive_system"moneō monēre, monuī, monitus")
	puts y

And the output?

	laudō laudāre laudāvī laudatus
	First Singular  laudōr    laudābār       laudābō
	Second Singular laudāris  laudābāris     laudāberis
	Third Singular  laudātur  laudābātur     laudābitur
	First Plural    laudāmur  laudābāmur     laudābimur
	Second Plural   laudāminī laudābāminī   laudābiminī
	Third Plural    laudāntur laudābāntur    laudābintur

	moneō monēre monuī monitus
	First Singular  moneōr    monēbār        monēbō
	Second Singular monēris   monēbāris      monēberis
	Third Singular  monētur   monēbātur      monēbitur
	First Plural    monēmur   monēbāmur      monēbimur
	Second Plural   monēminī monēbāminī    monēbiminī
	Third Plural    monēntur  monēbāntur     monēbintur

I don’t think that you have to be a Ruby guru to see that Ruby code is incredibly tight. Interestingly enough, Latin, as according to the gospel of Wheelocki, is taught in a very programmatic heuristic manner. You’re taught to carry a certain data file of critical givens on your biological hard drive ( a verb has 4 principal parts, the principal parts of “to praise” …. ) and then are taught a series of transformations to be performed on those 4 principal parts. Working those out is an exercise being a mental computer, mutating data according to heuristic and spitting it out.

Interestingly, when printing technology was much more expensive ( or, students were much more rebellion-prone when forced to pay outrageous prices for books ) Latin instruction was a few terse rules and the homework was “Write out the application of these heuristics to the following data items”. With the rules, and the given inputs, the human scribbler would write out the references he would need to be able to advance to the next chapter.

I have a certain admiration for this method.

But I also have ruby, and remembering how i applied a few map()s or flatten!() statements is just as good.