Description

This library provides a ruby implementation of a Table data structure from lua.

Tables are essentially a combination of hashes and arrays.

They're more for convenience than anything else, but they provide setters and getters for symbolized keys in hashes and uniform hash and array like access.

Any methods from the Enumerable module should work and will treat the table as an array, ignoring any pairs inside it.

Caveats

Like a hash, the order for paired objects is not guaranteed.

Also, as in lua, hash keys cannot be numeric indices. If you intend to use numeric hash keys, they should be inside an array, such as:

Table[ [ 2 ] => 4 ]

Unlike in lua, where an error is raised if you attempt to use numerical keys, ruby-tables will change all numerical keys into [ index ] as shown above.

That is:

t = Table[ 1, 2, 3, { 4 => 5 } ]
t[ 4 ] = 5
t.pairs #=> { [ 4 ] => 5 }
t.to_a #=> [ 1, 2, 3, nil, 5 ]
t[ [ 4 ] ] = 50
t.pairs #=> { [ 4 ] => 50 }

Notice above that index 3 was set to a nil value. That's because numeric indexes are filled in when you create a key well out of bounds. This is not unlike typical ruby Arrays:

ary = [ 1 ]
ary[ 10 ] = 2
ary #=> [ 1, nil, nil, nil, nil, nil, nil, nil, nil, nil, 2 ]

Usage

Install it:

gem install ruby-tables

Use it:

require "rubygems"
require "table"

Examples

# as hashes with convient dot notation for keys
t1 = Table[ :something => 50, :else => 100 ]
t1.something #=> 50
t1.something = 100
t1.something #=> 100
t1.some_new_key = "sdsdsd"
t1.some_new_key #=> "sdsdsd"
t1.users = Table[ *%w{ Tom Dick Harry }.map { | n | Table[ :name => n ] } ]

t1.users.first.name #=> Tom
t1.users.first.name = "Alex"
t1.users.map { | u | u.name }.join( ", " ) #=> Alex, Dick, Harry

# as a combination of an array and a hash
t2 = Table[ 1, 2, 3, 4, 5, { :a => 1000, :b => 2000 }, 6, 7, { :c => 50, :d => 60 }, 8, 9 ]

# the size method returns the number of array values inside the table, this is identical
# to lua's length operator (#table)
t2.size #=> 9

t2.each_pair { | k, v | print k } #=> abcd

# tables can be concatenated
t3 = t1 + t2

# you can access the array elements or the hash elements as their underlying structures
t3.pairs #=> { :something => 50, :else => 100, :a => 1000, :b => 2000, :c => 50, :d => 60 }
t3.to_a #=> [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
t3.inject { |sum, i | sum + i } #=> 45

# other examples
t = Table[ 1, 2, 3, 4, { :a => "1", :b => "2" }, 7, 8 ]
t #=> Table[1, 2, 3, 4, 7, 8, {:b=>"2", :a=>"1"}]

t.size #=> 8
t.b #=> "2"

t.b = Table[ 255, 0, 0, { :color => "red" } ]
t.b.color #=> "red"
r, b, g = *t.b
print r, g, b #=> 25500

t #=> Table[1, 2, 3, 4, 7, 8, {:b=>Table[255, 0, 0, {:color=>"red"}], :a=>"1", :c=>"3"}]

t << %{ a b c d }
t.last #=> ["a", "b", "c", "d"]
t[ -3 ] #=> 7

t #=> Table[1, 2, 3, 4, 7, 8, ["a", "b", "c", "d"], {:b=>Table[255, 0, 0, {:color=>"red"}], :a=>"1", :c=>"3"}]