I have some embarrassingly long code which puts into words any number up into the trillions. As a newbie, and understanding that shorter, non-repetitive code is best, I am looking for suggestions on how to reduce this code to a respectable quantity. I realize that there is a lot of repetition in it. However, depending on the number being evaluated, the math looks a little different with each rep, so I am not sure if I can reduce that. I have tried rewriting it solely as an if/else (without the recursion) but it quickly becomes just as bad if not worse.class :: Fixnum   def in_words(number)    if number < 0  # No negative numbers.      return 'Please enter a number that isn\'t negative.'    end    if number == 0      return 'zero'    end  numString = ''  # This is the string we will return.  onesPlace = ['one',     'two',       'three',    'four',     'five',               'six',     'seven',     'eight',    'nine']  tensPlace = ['ten',     'twenty',    'thirty',   'forty',    'fifty',               'sixty',   'seventy',   'eighty',   'ninety']  teenagers = ['eleven',  'twelve',    'thirteen', 'fourteen', 'fifteen',               'sixteen', 'seventeen', 'eighteen', 'nineteen']    #-----------------------------------------trillions  left = number   write = left/1000000000000  left = left - (write*1000000000000)    if number > 999999999999      if write < 10 #1,00 - 9,000        millions  = onesPlace[write - 1]        numString = numString + millions + ' trillion'      end       if (write > 9) && (write < 20) #10,000 - 19,000        if write == 10           millions = tensPlace[write - 10]          numString = numString + millions + ' trillion'        else            millions = teenagers[write - 11] #11 because the length of teenagers is only 9 so 15-11 = 4 and 'thirteen' is in           numString = numString + millions + ' trillion'        end      end      if (write > 19) && (write < 1000) #here i have to use recursion to get the first two/three digets --> 19,000,000 - 999,000,000        millions = in_words(write)        numString = numString + millions + ' trillion'      end      if left > 0        numString = numString + ' '      end    #-----------------------------------------billions  #left = number   write = left/1000000000  left = left - (write*1000000000)    if number > 999999999      if write < 10 #1,00 - 9,000        millions  = onesPlace[write - 1]        numString = numString + millions + ' billion'      end       if (write > 9) && (write < 20) #10,000 - 19,000        if write == 10           millions = tensPlace[write - 10]          numString = numString + millions + ' billion'        else            millions = teenagers[write - 11] #11 because the length of teenagers is only 9 so 15-11 = 4 and 'thirteen' is in           numString = numString + millions + ' billion'        end      end      if (write > 19) && (write < 1000) #here i have to use recursion to get the first two/three digets --> 19,000,000 - 999,000,000        millions = in_words(write)        numString = numString + millions + ' billion'      end      if left > 0        numString = numString + ' '      end # ----------------------------------------millions  write = left/1000000  left = left - (write*1000000)    if number > 999999      if write < 10 #1,00 - 9,000        millions  = onesPlace[write - 1]        numString = numString + millions + ' million'      end       if (write > 9) && (write < 20) #10,000 - 19,000        if write == 10           millions = tensPlace[write - 10]          numString = numString + millions + ' million'        else            millions = teenagers[write - 11] #11 because the length of teenagers is only 9 so 15-11 = 4 and 'thirteen' is in           numString = numString + millions + ' million'        end      end      if (write > 19) && (write < 1000) #here i have to use recursion to get the first two/three digets --> 19,000,000 - 999,000,000        millions = in_words(write)        numString = numString + millions + ' million'      end      if left > 0        numString = numString + ' '      end #-----------------------------------------thousands   write = left/1000  left = left - (write*1000)    if number > 999         if write < 10 #1,00 - 9,000        thousands  = onesPlace[write - 1]        numString = numString + thousands + ' thousand'      end       if (write > 9) && (write < 20) #10,000 - 19,000        if write == 10           thousands = tensPlace[write - 10]          numString = numString + thousands + ' thousand'        else            thousands = teenagers[write - 11] #11 because the length of teenagers is only 9 so 15-11 = 4 and 'thirteen' is in           numString = numString + thousands + ' thousand'        end      end      if (write > 19) && (write < 1000) #here i have to use recursion to get the first two/three digits --> 19,000 - 999,000        thousands = in_words(write)        numString = numString + thousands + ' thousand'      end      if left > 0        numString = numString + ' '      end   end endend end# ------------- hundreds  write = left/100             left  = left - (write*100)    if write > 0    hundreds  = in_words(write)     numString = numString + hundreds + ' hundred'    if left > 0      numString = numString + ' '     end  end# ---------------- tens     write = left/10    #stop here and return     #numString = numString +   left  = left - write*10       if write > 0       if ((write == 1) and (left > 0))          numString = numString + teenagers[left-1]          left = 0    else      numString = numString + tensPlace[write-1]    end    if left > 0      numString = numString + '-'    end  end   write = left     left  = 0       if write > 0    numString = numString + onesPlace[write-1]  end  numStringendend#classputs 95202824653012.in_words(95202824653012)Another problem I have with it is that it is a method added to the Fixnum class and I would like to be able to call it directly on self without an argument, for example 3457278.in_words instead of 3457278.in_words(3457278). The problem seems to be that the recursion needs an argument when it is called, and therefore the method needs one. Or is there a way around that?
Putting numbers into words
ruby;numbers to words
Rather than rewrite your whole solution, I'll point out more idiomatic ways to do this stuff in Ruby.RecursionYou don't need an argument to do recursion, self is enough.class ::Fixnum  def in_words    # ...    millions = write.in_words    # ...  endendString Arrays%w{} is handy for making arrays containing one-word stringsones_place = %{one two three four five six seven eight nine}Long Numbers_ can be used like a comma (or period, if you're European) in long numbers.billion = 1_000_000_000For powers of 10, you can also use exponentiationtrillion = 10 ** 12Modulus% gets the remainder of a number after dividing.write = left / 10 ** 9left = left % 10 ** 9Assignment Shortcutx = x <op> y can be written as x <op>= y where <op> is any operator.numString += ' 'left %= 10 ** 9LoopsOnce you incorporate all of those, you should be able to see how that huge nested if can be turned into a tiny[12, 9, 6, 3].each do |power|  break if self < 10 ** power  # ...end