class Tuple

Tuple

Tuple is essentially an Array, but Comaparable and Immutable.

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

t1.to_s  #=> "1.2.3"
t2.to_s  #=> "1.2.3"

(t1 == t2)  #=> true

Keep in mind that Tuple is not the same as Tuple.

Constants

SEGMENT_SEPARATOR

Attributes

default[RW]

Public Instance Methods

<<( obj ) click to toggle source

Unlike Array, Tuple#<< cannot act in place becuase Tuple’s are immutable.

# File lib/supplemental/facets/tuple.rb, line 124
def <<( obj )
  self.class.instance( to_a << obj )
end
<=>( other ) click to toggle source
# File lib/supplemental/facets/tuple.rb, line 151
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
=~( other ) click to toggle source

For pessimistic constraint (like ‘~>’ in gems)

# File lib/supplemental/facets/tuple.rb, line 161
def =~( other )
  other = other.to_t
  upver = other.dup
  upver[0] += 1
  self >= other and self < upver
end
[](i) click to toggle source
# File lib/supplemental/facets/tuple.rb, line 111
def [](i)
  @values.fetch(i,@default)
end
[]=(i,v) click to toggle source
# File lib/supplemental/facets/tuple.rb, line 115
def []=(i,v)
  @values[i] = v
end
each( &block ) click to toggle source
# File lib/supplemental/facets/tuple.rb, line 103
def each( &block )
  @values.each( &block )
end
each_index( &block ) click to toggle source
# File lib/supplemental/facets/tuple.rb, line 107
def each_index( &block )
  @values.each_index( &block )
end
empty?() click to toggle source
# File lib/supplemental/facets/tuple.rb, line 97
def empty?()
  return true if @values.empty?
  return true if @values == [ @default ] * @values.size
  false
end
eql?( other ) click to toggle source

Returns true if two tuple references are for the very same tuple.

# File lib/supplemental/facets/tuple.rb, line 145
def eql?( other )
  return true if object_id == other.object_id
  ##return true if values.eql? other.values
end
first() click to toggle source
# File lib/supplemental/facets/tuple.rb, line 168
def first() @values.first end
hash() click to toggle source

Unique hash value.

# File lib/supplemental/facets/tuple.rb, line 177
def hash
  # TODO: This needs to take into account the default
  # and maybe the divider too.
  to_a.hash
end
index() click to toggle source
# File lib/supplemental/facets/tuple.rb, line 119
def index()  @values.index end
inspect() click to toggle source
# File lib/supplemental/facets/tuple.rb, line 82
def inspect() to_a.inspect end
last() click to toggle source
# File lib/supplemental/facets/tuple.rb, line 169
def last()  @values.last end
length() click to toggle source
# File lib/supplemental/facets/tuple.rb, line 95
def length() @values.size end
major() click to toggle source

These are useful for using a Tuple as a version.

# File lib/supplemental/facets/tuple.rb, line 172
def major() @values.first end
minor() click to toggle source
# File lib/supplemental/facets/tuple.rb, line 173
def minor() @values.at(1) end
pop() click to toggle source
# File lib/supplemental/facets/tuple.rb, line 128
def pop() Tuple.instance( to_a.pop ) end
pot( obj ) click to toggle source

Stands for “Put On Top”. This method is the opposite of #pull and is otherwise known as #unshift.

# File lib/supplemental/facets/tuple.rb, line 138
def pot( obj ) Tuple.instance( to_a.unshift(obj) ) end
Also aliased as: unshift
pull() click to toggle source

Pulls a value off the beginning of a tuple. This method is otherwsie known as #shift.

# File lib/supplemental/facets/tuple.rb, line 134
def pull() Tuple.instance( to_a.shift ) end
Also aliased as: shift
push( obj ) click to toggle source
# File lib/supplemental/facets/tuple.rb, line 130
def push( obj ) Tuple.instance( to_a.push(obj) ) end
rindex() click to toggle source
# File lib/supplemental/facets/tuple.rb, line 120
def rindex() @values.rindex end
shift() click to toggle source
Alias for: pull
size() click to toggle source
# File lib/supplemental/facets/tuple.rb, line 94
def size()   @values.size end
teeny() click to toggle source
# File lib/supplemental/facets/tuple.rb, line 174
def teeny() @values.at(2) end
to_a() click to toggle source
# File lib/supplemental/facets/tuple.rb, line 87
def to_a()   Array(@values) end
to_ary() click to toggle source
# File lib/supplemental/facets/tuple.rb, line 88
def to_ary() Array(@values) end
to_s(divider=nil) click to toggle source
# File lib/supplemental/facets/tuple.rb, line 90
def to_s(divider=nil)
  @values.join(divider || SEGMENT_SEPARATOR)
end
to_t() click to toggle source
# File lib/supplemental/facets/tuple.rb, line 84
def to_t()     self end
to_tuple() click to toggle source
# File lib/supplemental/facets/tuple.rb, line 85
def to_tuple() self end
unshift( obj ) click to toggle source
Alias for: pot

Protected Instance Methods

values() click to toggle source

def divider( set=nil )

return @divider unless set
@divider = set
self

end

# File lib/supplemental/facets/tuple.rb, line 76
def values() @values end

Public Class Methods

[]( *args ) click to toggle source
# File lib/supplemental/facets/tuple.rb, line 188
def []( *args )
  instance( args )
end
cast_from_array( arr ) click to toggle source
# File lib/supplemental/facets/tuple.rb, line 217
def cast_from_array( arr )
  self.instance( arr )
end
cast_from_string( str, &yld ) click to toggle source

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/supplemental/facets/tuple.rb, line 205
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
constraint_to_lambda( constraint, &yld ) click to toggle source

Parses a constraint returning the operation as a lambda.

# File lib/supplemental/facets/tuple.rb, line 222
def constraint_to_lambda( constraint, &yld )
  op, val = *parse_constraint( constraint, &yld )
  lambda { |t| t.send(op, val) }
end
multiton_id(arg=0, default=0, &block) click to toggle source
# File lib/supplemental/facets/tuple.rb, line 41
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
new(arg=0, default=0, &blk) click to toggle source
# File lib/supplemental/facets/tuple.rb, line 53
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
parse_constraint( constraint, &yld ) click to toggle source
# File lib/supplemental/facets/tuple.rb, line 228
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