def combination(n)
      return enum_for(:combination, n) if not block_given?
      return self if n < 0 || @size < n
      if n == 0
        yield []
      elsif n == 1
        each { |element| yield [element] }
      elsif n == @size
        yield self.to_a
      else
        combos = lambda do |result,index,remaining|
          while @size - index > remaining
            if remaining == 1
              yield result.dup << get(index)
            else
              combos[result.dup << get(index), index+1, remaining-1]
            end
            index += 1
          end
          index.upto(@size-1) { |i| result << get(i) }
          yield result
        end
        combos[[], 0, n]
      end
      return self
    end
def combination(n)
      return enum_for(:combination, n) if not block_given?
      return self if n < 0 || @size < n
      if n == 0
        yield []
      elsif n == 1
        each { |element| yield [element] }
      elsif n == @size
        yield self.to_a
      else
        combos = lambda do |result,index,remaining|
          while @size - index > remaining
            if remaining == 1
              yield result.dup << get(index)
            else
              combos[result.dup << get(index), index+1, remaining-1]
            end
            index += 1
          end
          index.upto(@size-1) { |i| result << get(i) }
          yield result
        end
        combos[[], 0, n]
      end
      return self
    end
When invoked with a block, yields all combinations of length `n` of elements
 from the `Tuple`, and then returns `self`. There is no guarantee about
 which order the combinations will be yielded.

 If no block is given, an `Enumerator` is returned instead.

 @example
   t = Erlang::Tuple[5, 6, 7, 8]
   t.combination(3) { |c| puts "Combination: #{c}" }

   Combination: [5, 6, 7]
   Combination: [5, 6, 8]
   Combination: [5, 7, 8]
   Combination: [6, 7, 8]
   #=> Erlang::Tuple[5, 6, 7, 8]

 @return [self, Enumerator]