Got an iPhone or iPad? We have a brand new Pastebin App for both devices, and it's totally free! Click here to download the new Pastebin App for iOS.
Guest

Ruby, does it allow Cartesian product constructors

By: a guest on Feb 23rd, 2012  |  syntax: None  |  size: 1.06 KB  |  hits: 31  |  expires: Never
download  |  raw  |  embed  |  report abuse
Copied
  1. class Tuple
  2.   include Enumerable; include Comparable
  3.  
  4.   class << self
  5.     alias_method :[], :new
  6.  
  7.     def call(length)
  8.       class_name = :"Tuple#{length}"
  9.       return const_get class_name if const_defined? class_name
  10.       const_set class_name, Class.new(self) {
  11.         (@length = length).times do |i| define_method :"_#{i+1}" do @ary[i] end end
  12.       }
  13.     end
  14.   end
  15.  
  16.   def to_s; "(#{@ary.join(', ')})" end
  17.   def inspect; "#<#{self.class} (#{@ary.map(&:inspect).join(', ')})>" end
  18.   def to_a; @ary.dup end
  19.   def [](*args) @ary[*args] end
  20.   def each(*args, &block) @ary.each(*args, &block) end
  21.  
  22.   def <=>(other)
  23.     raise TypeError unless other.is_a? self.class
  24.     raise TypeError unless each_with_index.all? {|el, i| other.instance_variable_get(:@ary)[i].instance_of?(el.class) }
  25.     map.with_index {|el, i| el <=> other.instance_variable_get(:@ary)[i] }.find(0) {|cmp| !cmp.zero? }
  26.   end
  27.  
  28.   def initialize(*args)
  29.     raise ArgumentError unless args.length == self.class.instance_variable_get(:@length)
  30.     (@ary = args).freeze
  31.   end
  32. end
  33.        
  34. t3 = Tuple.(3)[1, :two, 'three']