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’].

Methods
<< <=> =~ [] [] []= cast_from_array cast_from_string constraint_to_lambda divider each each_index empty? eql? first hash index inspect last length major minor multiton_id new parse_constraint pop pot pull push rindex shift size teeny to_a to_ary to_s to_t to_tuple unshift values
Included Modules
Attributes
[RW] default
Public Class methods
[]( *args )
# File lib/more/facets/tuple.rb, line 226
    def []( *args )
      instance( args )
    end
cast_from_array( arr )
# File lib/more/facets/tuple.rb, line 257
    def cast_from_array( arr )
      self.instance( arr )
    end
cast_from_string( str, &yld )

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
constraint_to_lambda( constraint, &yld )

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
multiton_id(arg=0, default=0, &block)
# 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
new(arg=0, default=0, &blk)
# 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
parse_constraint( constraint, &yld )
# 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
Public Instance methods
<<( obj )

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

# File lib/more/facets/tuple.rb, line 164
  def <<( obj )
    self.class.instance( to_a << obj )
  end
<=>( other )
# 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
=~( other )

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
[](i)
# File lib/more/facets/tuple.rb, line 151
  def [](i)
    @values.fetch(i,@default)
  end
[]=(i,v)
# File lib/more/facets/tuple.rb, line 155
  def []=(i,v)
    @values[i] = v
  end
divider( set=nil )
# File lib/more/facets/tuple.rb, line 110
  def divider( set=nil )
    return @divider unless set
    @divider = set
    self
  end
each( &block )
# File lib/more/facets/tuple.rb, line 143
  def each( &block )
    @values.each( &block )
  end
each_index( &block )
# File lib/more/facets/tuple.rb, line 147
  def each_index( &block )
    @values.each_index( &block )
  end
empty?()
# File lib/more/facets/tuple.rb, line 137
  def empty?()
    return true if @values.empty?
    return true if @values == [ @default ] * @values.size
    false
  end
eql?( other )

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
first()
# File lib/more/facets/tuple.rb, line 207
  def first() @values.first end
hash()

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
index()
# File lib/more/facets/tuple.rb, line 159
  def index()  @values.index end
inspect()
# File lib/more/facets/tuple.rb, line 122
  def inspect() to_a.inspect end
last()
# File lib/more/facets/tuple.rb, line 208
  def last()  @values.last end
length()
# File lib/more/facets/tuple.rb, line 135
  def length() @values.size end
major()

These are useful for using a Tuple as a version.

# File lib/more/facets/tuple.rb, line 211
  def major() @values.first end
minor()
# File lib/more/facets/tuple.rb, line 212
  def minor() @values.at(1) end
pop()
# File lib/more/facets/tuple.rb, line 168
  def pop() Tuple.instance( to_a.pop ) end
pot( obj )

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

This method is also aliased as unshift
# File lib/more/facets/tuple.rb, line 178
  def pot( obj ) Tuple.instance( to_a.unshift(obj) ) end
pull()

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

This method is also aliased as shift
# File lib/more/facets/tuple.rb, line 174
  def pull() Tuple.instance( to_a.shift ) end
push( obj )
# File lib/more/facets/tuple.rb, line 170
  def push( obj ) Tuple.instance( to_a.push(obj) ) end
rindex()
# File lib/more/facets/tuple.rb, line 160
  def rindex() @values.rindex end
shift()

Alias for pull

size()
# File lib/more/facets/tuple.rb, line 134
  def size()   @values.size end
teeny()
# File lib/more/facets/tuple.rb, line 213
  def teeny() @values.at(2) end
to_a()
# File lib/more/facets/tuple.rb, line 127
  def to_a()   Array(@values) end
to_ary()
# File lib/more/facets/tuple.rb, line 128
  def to_ary() Array(@values) end
to_s( divider=nil )
# File lib/more/facets/tuple.rb, line 130
  def to_s( divider=nil )
    @values.join(divider||@divider)
  end
to_t()
# File lib/more/facets/tuple.rb, line 124
  def to_t()     self end
to_tuple()
# File lib/more/facets/tuple.rb, line 125
  def to_tuple() self end
unshift( obj )

Alias for pot

Protected Instance methods
values()
# File lib/more/facets/tuple.rb, line 118
  def values() @values end