Class | Tuple |
In: |
lib/more/facets/tuple.rb
|
Parent: | Object |
A tuple can be made using new or #[] just as one builds an array, or using the to_t 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’].
default | [RW] |
# 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 = %r{^(=~|~>|<=|>=|==|=|<|>)?\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
# 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 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 130 130: def to_s( divider=nil ) 131: @values.join(divider||@divider) 132: end