Tuple
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.
Usage
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’].
- ::Multiton
- ::Enumerable
- ::Comparable
[RW] | default |
[ + ]
# File lib/more/facets/tuple.rb, line 226 def []( *args ) instance( args ) end
[ + ]
# File lib/more/facets/tuple.rb, line 257 def cast_from_array( arr ) self.instance( arr ) 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 def cast_from_string( str, &yld ) args = str.to_s.split(/\W+/) div = /\W+/.match( str.to_s )[0] if block_given? args = args.collect{ |a| yld[a] } else args = args.collect { |i| /^[0-9]+$/ =~ i ? i.to_i : i } end self.instance( args ).divider( div ) end
Parses a constraint returning the operation as a lambda.
[ + ]
# File lib/more/facets/tuple.rb, line 263 def constraint_to_lambda( constraint, &yld ) op, val = *parse_constraint( constraint, &yld ) lambda { |t| t.send(op, val) } end
[ + ]
# File lib/more/facets/tuple.rb, line 83 def self.multiton_id(arg=0, default=0, &block) if block_given? values = [] arg.times { |i| values << block[i] } elseif Integer === arg values = [ default ] * arg else values = arg.to_ary end values end
[ + ]
# File lib/more/facets/tuple.rb, line 95 def initialize(arg=0, default=0, &blk) if block_given? @values = [] arg.times { |i| @values << blk[i] } elseif Integer === arg @values = [ default ] * arg else @values = arg.to_ary end @default = default @divider = '.' end
[ + ]
# File lib/more/facets/tuple.rb, line 268 def parse_constraint( constraint, &yld ) constraint = constraint.strip re = %r{^(=~|~>|<=|>=|==|=|<|>)?\s*(\d+(:?[-.]\d+)*)$} if md = re.match( constraint ) if op = md[1] op = '=~' if op == '~>' op = '==' if op == '=' val = cast_from_string( md[2], &yld ) #instance( md[2] ) else op = '==' val = cast_from_string( constraint, &yld ) #instance( constraint ) end else raise ArgumentError, "invalid constraint" end return op, val end
[ + ]
# File lib/more/facets/tuple.rb, line 164 def <<( obj ) self.class.instance( to_a << obj ) end
[ + ]
# File lib/more/facets/tuple.rb, line 190 def <=>( other ) other = other.to_t [size, other.size].max.times do |i| c = self[i] <=> other[i] return c if c != 0 end 0 end
For pessimistic constraint (like ’~>’ in gems)
[ + ]
# File lib/more/facets/tuple.rb, line 200 def =~( other ) other = other.to_t upver = other.dup upver[0] += 1 self >= other and self < upver end
[ + ]
# File lib/more/facets/tuple.rb, line 151 def [](i) @values.fetch(i,@default) end
[ + ]
# File lib/more/facets/tuple.rb, line 155 def []=(i,v) @values[i] = v end
[ + ]
# File lib/more/facets/tuple.rb, line 110 def divider( set=nil ) return @divider unless set @divider = set self end
[ + ]
# File lib/more/facets/tuple.rb, line 143 def each( &block ) @values.each( &block ) end
[ + ]
# File lib/more/facets/tuple.rb, line 147 def each_index( &block ) @values.each_index( &block ) end
[ + ]
# File lib/more/facets/tuple.rb, line 137 def empty?() return true if @values.empty? return true if @values == [ @default ] * @values.size false end
Returns true if two tuple references are for the very same tuple.
[ + ]
# File lib/more/facets/tuple.rb, line 185 def eql?( other ) return true if object_id == other.object_id #return true if values.eql? other.values end
[ + ]
# File lib/more/facets/tuple.rb, line 207 def first() @values.first end
Unique hash value.
[ + ]
# File lib/more/facets/tuple.rb, line 216 def hash # TODO This needs to take into account the default # and maybe the divider too. to_a.hash end
[ + ]
# File lib/more/facets/tuple.rb, line 159 def index() @values.index end
[ + ]
# File lib/more/facets/tuple.rb, line 122 def inspect() to_a.inspect end
[ + ]
# File lib/more/facets/tuple.rb, line 208 def last() @values.last end
[ + ]
# File lib/more/facets/tuple.rb, line 135 def length() @values.size end
These are useful for using a Tuple as a version.
[ + ]
# File lib/more/facets/tuple.rb, line 211 def major() @values.first end
[ + ]
# File lib/more/facets/tuple.rb, line 212 def minor() @values.at(1) end
[ + ]
# File lib/more/facets/tuple.rb, line 168 def pop() Tuple.instance( to_a.pop ) end
[ + ]
# File lib/more/facets/tuple.rb, line 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 shift.
[ + ]
# File lib/more/facets/tuple.rb, line 174 def pull() Tuple.instance( to_a.shift ) end
[ + ]
# File lib/more/facets/tuple.rb, line 170 def push( obj ) Tuple.instance( to_a.push(obj) ) end
[ + ]
# File lib/more/facets/tuple.rb, line 160 def rindex() @values.rindex end
Alias for pull
[ + ]
# File lib/more/facets/tuple.rb, line 134 def size() @values.size end
[ + ]
# File lib/more/facets/tuple.rb, line 213 def teeny() @values.at(2) end
[ + ]
# File lib/more/facets/tuple.rb, line 127 def to_a() Array(@values) end
[ + ]
# File lib/more/facets/tuple.rb, line 128 def to_ary() Array(@values) end
[ + ]
# File lib/more/facets/tuple.rb, line 130 def to_s( divider=nil ) @values.join(divider||@divider) end
[ + ]
# File lib/more/facets/tuple.rb, line 124 def to_t() self end
[ + ]
# File lib/more/facets/tuple.rb, line 125 def to_tuple() self end
Alias for pot
[ + ]
# File lib/more/facets/tuple.rb, line 118 def values() @values end