A tuple can be made using # or #[] just as one builds an array, or using the # method on a string or array. With a string tuple remembers the first non-alphanumeric character as the tuple divider.
t1 = Tuple[1,2,3] t2 = Tuple[2,3,4] t1 < t2 #=> true t1 > t2 #=> false t1 = '1.2.3'.to_t t2 = '1-2-3'.to_t puts t1 #=> 1.2.3 puts t2 #=> 1-2-3 t1 == t2 #=> true
Keep in mind that Tuple[1,2,3] is not the same as Tuple[‘1’,’2’,’3’].
# File lib/more/facets/tuple.rb, line 226 226: def []( *args ) 227: instance( args ) 228: end
# File lib/more/facets/tuple.rb, line 257 257: def cast_from_array( arr ) 258: self.instance( arr ) 259: end
Translates a string in the form on a set of numerical and/or alphanumerical characters separated by non-word characters (eg W+) into a Tuple. The values of the tuple will be converted to integers if they are purely numerical.
Tuple.cast_from_string('1.2.3a') #=> [1,2,"3a"]
It you would like to control the interpretation of each value as it is added to the tuple you can supply a block.
Tuple.cast_from_string('1.2.3a'){ |v| v.upcase } #=> ["1","2","3A"]
This method is called by String#to_t.
# File lib/more/facets/tuple.rb, line 244 244: def cast_from_string( str, &yld ) 245: args = str.to_s.split(/\W+/) 246: div = /\W+/.match( str.to_s )[0] 247: if block_given? 248: args = args.collect{ |a| yld[a] } 249: else 250: args = args.collect { |i| /^[0-9]+$/ =~ i ? i.to_i : i } 251: end 252: self.instance( args ).divider( div ) 253: end
Parses a constraint returning the operation as a lambda.
# File lib/more/facets/tuple.rb, line 263 263: def constraint_to_lambda( constraint, &yld ) 264: op, val = *parse_constraint( constraint, &yld ) 265: lambda { |t| t.send(op, val) } 266: end
# File lib/more/facets/tuple.rb, line 83 83: def self.multiton_id(arg=0, default=0, &block) 84: if block_given? 85: values = [] 86: arg.times { |i| values << block[i] } 87: elseif Integer === arg 88: values = [ default ] * arg 89: else 90: values = arg.to_ary 91: end 92: values 93: end
# File lib/more/facets/tuple.rb, line 95 95: def initialize(arg=0, default=0, &blk) 96: if block_given? 97: @values = [] 98: arg.times { |i| @values << blk[i] } 99: elseif Integer === arg 100: @values = [ default ] * arg 101: else 102: @values = arg.to_ary 103: end 104: @default = default 105: @divider = '.' 106: end
# File lib/more/facets/tuple.rb, line 268 268: def parse_constraint( constraint, &yld ) 269: constraint = constraint.strip 270: re = %{^(=~|~>|<=|>=|==|=|<|>)?\s*(\d+(:?[-.]\d+)*)$} 271: if md = re.match( constraint ) 272: if op = md[1] 273: op = '=~' if op == '~>' 274: op = '==' if op == '=' 275: val = cast_from_string( md[2], &yld ) #instance( md[2] ) 276: else 277: op = '==' 278: val = cast_from_string( constraint, &yld ) #instance( constraint ) 279: end 280: else 281: raise ArgumentError, "invalid constraint" 282: end 283: return op, val 284: end
Unlike Array, Tuple#<< cannot act in place becuase Tuple’s are immutable.
# File lib/more/facets/tuple.rb, line 164 164: def <<( obj ) 165: self.class.instance( to_a << obj ) 166: end
# File lib/more/facets/tuple.rb, line 190 190: def <=>( other ) 191: other = other.to_t 192: [size, other.size].max.times do |i| 193: c = self[i] <=> other[i] 194: return c if c != 0 195: end 196: 0 197: end
For pessimistic constraint (like ’~>’ in gems)
# File lib/more/facets/tuple.rb, line 200 200: def =~( other ) 201: other = other.to_t 202: upver = other.dup 203: upver[0] += 1 204: self >= other and self < upver 205: end
# File lib/more/facets/tuple.rb, line 151 151: def [](i) 152: @values.fetch(i,@default) 153: end
# File lib/more/facets/tuple.rb, line 155 155: def []=(i,v) 156: @values[i] = v 157: end
# File lib/more/facets/tuple.rb, line 110 110: def divider( set=nil ) 111: return @divider unless set 112: @divider = set 113: self 114: end
# File lib/more/facets/tuple.rb, line 143 143: def each( &block ) 144: @values.each( &block ) 145: end
# File lib/more/facets/tuple.rb, line 147 147: def each_index( &block ) 148: @values.each_index( &block ) 149: end
# File lib/more/facets/tuple.rb, line 137 137: def empty?() 138: return true if @values.empty? 139: return true if @values == [ @default ] * @values.size 140: false 141: end
Returns true if two tuple references are for the very same tuple.
# File lib/more/facets/tuple.rb, line 185 185: def eql?( other ) 186: return true if object_id == other.object_id 187: #return true if values.eql? other.values 188: end
# File lib/more/facets/tuple.rb, line 207 207: def first() @values.first end
Unique hash value.
# File lib/more/facets/tuple.rb, line 216 216: def hash 217: # TODO This needs to take into account the default 218: # and maybe the divider too. 219: to_a.hash 220: end
# File lib/more/facets/tuple.rb, line 159 159: def index() @values.index end
# File lib/more/facets/tuple.rb, line 122 122: def inspect() to_a.inspect end
# File lib/more/facets/tuple.rb, line 208 208: def last() @values.last end
# File lib/more/facets/tuple.rb, line 135 135: def length() @values.size end
These are useful for using a Tuple as a version.
# File lib/more/facets/tuple.rb, line 211 211: def major() @values.first end
# File lib/more/facets/tuple.rb, line 212 212: def minor() @values.at(1) end
# File lib/more/facets/tuple.rb, line 168 168: def pop() Tuple.instance( to_a.pop ) end
Stands for “Put On Top”. This method is the opposite of # and is otherwise known as #.
# File lib/more/facets/tuple.rb, line 178 178: def pot( obj ) Tuple.instance( to_a.unshift(obj) ) end
Pulls a value off the beginning of a tuple. This method is otherwsie known as #.
# File lib/more/facets/tuple.rb, line 174 174: def pull() Tuple.instance( to_a.shift ) end
# File lib/more/facets/tuple.rb, line 170 170: def push( obj ) Tuple.instance( to_a.push(obj) ) end
# File lib/more/facets/tuple.rb, line 160 160: def rindex() @values.rindex end
# File lib/more/facets/tuple.rb, line 134 134: def size() @values.size end
# File lib/more/facets/tuple.rb, line 213 213: def teeny() @values.at(2) end
# File lib/more/facets/tuple.rb, line 127 127: def to_a() Array(@values) end
# File lib/more/facets/tuple.rb, line 128 128: def to_ary() Array(@values) end
# File lib/more/facets/tuple.rb, line 130 130: def to_s( divider=nil ) 131: @values.join(divider||@divider) 132: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.