columnize (Columnize)

    # File lib/columnize.rb, line 56
      def columnize(list, displaywidth=80, colsep = '  ',
                    arrange_vertical=true, ljust=true, lineprefix='')

        # Some degenerate cases
        if not list.is_a?(Array)
          return ''
        end
        if list.size == 0
          return  "<empty>\n"
        end
        l = list.map{|li| li.to_s}
        if 1 == l.size
          return "#{l[0]}\n"
        end

        nrows = ncols = 0  # Make nrows, ncols have more global scope
        colwidths = []     # Same for colwidths
        displaywidth = [4, displaywidth - lineprefix.length].max
        if arrange_vertical
          array_index = lambda {|nrows, row, col| nrows*col + row }
          # Try every row count from 1 upwards
          1.upto(l.size-1) do |_nrows|
            nrows = _nrows
            ncols = (l.size + nrows-1) / nrows
            colwidths = []
            totwidth = -colsep.length

            0.upto(ncols-1) do |_col|
              col = _col
              # get max column width for this column
              colwidth = 0
              0.upto(nrows-1) do |_row|
                row = _row
                i = array_index.call(nrows, row, col)
                if i >= l.size
                  break
                end
                colwidth = [colwidth, l[i].size].max
              end
              colwidths << colwidth
              totwidth += colwidth + colsep.length
              if totwidth > displaywidth
                ncols = col
                break
              end
            end
            if totwidth <= displaywidth
              break
            end
          end
          # The smallest number of rows computed and the
          # max widths for each column has been obtained.
          # Now we just have to format each of the
          # rows.
          s = ''
          0.upto(nrows-1) do |_row|
            row = _row
            texts = []
            0.upto(ncols-1) do |_col|
              col = _col
              i = array_index.call(nrows, row, col)
              if i >= l.size
                x = ""
              else
                x = l[i]
              end
              texts << x
            end
            while texts and texts[-1] == ''
              texts = texts[0..-2]
            end
            if texts.size > 0
              0.upto(texts.size-1) do |_col|
                col = _col
                if ljust
                    texts[col] = texts[col].ljust(colwidths[col])
                else
                    texts[col] = texts[col].rjust(colwidths[col])
                end
              end
              s += "%s%s\n" % [lineprefix, texts.join(colsep)]
            end
          end
          return s
        else
          array_index = lambda {|nrows, row, col| ncols*(row-1) + col }
          # Try every column count from size downwards
          # Assign to make enlarge scope of loop variables
          totwidth = i = rounded_size = 0
          l.size.downto(0) do |_ncols|
            ncols = _ncols
            # Try every row count from 1 upwards
            min_rows = (l.size+ncols-1) / ncols
            min_rows.upto(l.size) do |_nrows|
              nrows = _nrows
              rounded_size = nrows * ncols
              colwidths = []
              totwidth = -colsep.length
              colwidth = row = 0
              0.upto(ncols-1) do |_col|
                col = _col
                # get max column width for this column
                1.upto(nrows) do |_row|
                  row = _row
                  i = array_index.call(nrows, row, col)
                  if i >= rounded_size
                    break
                  elsif i < l.size
                    colwidth = [colwidth, l[i].size].max
                  end
                end
                colwidths << colwidth
                totwidth += colwidth + colsep.length
                if totwidth > displaywidth
                  break
                end
              end
              if totwidth <= displaywidth
                # Found the right nrows and ncols
                nrows  = row
                break
              elsif totwidth >= displaywidth
                # Need to reduce ncols
                break
              end
            end
            if totwidth <= displaywidth and i >= rounded_size-1
                break
            end
          end
          # The smallest number of rows computed and the
          # max widths for each column has been obtained.
          # Now we just have to format each of the
          # rows.
          s = ''
          1.upto(nrows) do |row|
            texts = []
            0.upto(ncols-1) do |col|
              i = array_index.call(nrows, row, col)
              if i >= l.size
                break
              else
                x = l[i]
              end
              texts << x
            end
            0.upto(texts.size-1) do |col|
              if ljust
                texts[col] = texts[col].ljust(colwidths[col])
              else
                texts[col] = texts[col].rjust(colwidths[col])
              end
            end
            s += "%s%s\n" % [lineprefix, texts.join(colsep)]
          end
          return s
        end
      end