ruby-tables 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ *.swp
@@ -0,0 +1,56 @@
1
+ = Description
2
+ This library provides a ruby implementation of a Table data structure from lua.
3
+
4
+ Tables are essentially a combination of hashes and arrays.
5
+
6
+ They're more for convenience than anything else, but they provide setters and getters
7
+ for symbolized keys in hashes and uniform hash and array like access.
8
+
9
+ Any methods from the Enumerable module should work and will treat the table as an array,
10
+ ignoring any pairs inside it.
11
+
12
+ = Caveats
13
+ As in lua, hash keys cannot be numeric indices. If you intend to use numeric hash keys,
14
+ they should be inside an array, such as:
15
+ Table[ [ 2 ] => 4 ]
16
+
17
+ Unlike in lua, where an error is raised if you attempt to use numerical keys, ruby-tables
18
+ will change all numerical keys into [ index ] as shown above.
19
+
20
+ That is:
21
+ t = Table[ 1, 2, 3, { 4 => 5 } ]
22
+ t[ 4 ] = 5
23
+ t.pairs #=> { [ 4 ] => 5 }
24
+ t.to_a #=> [ 1, 2, 3, nil, 5 ]
25
+ t[ [ 4 ] ] = 50
26
+ t.pairs #=> { [ 4 ] => 50 }
27
+
28
+ Notice above that index 3 was set to a nil value. That's because numeric indexes are filled
29
+ in when you create a key well out of bounds. This is not unlike typical ruby Arrays:
30
+ ary = [ 1 ]
31
+ ary[ 10 ] = 2
32
+ ary #=> [ 1, nil, nil, nil, nil, nil, nil, nil, nil, nil, 2 ]
33
+
34
+ = Examples
35
+ # as hashes with convient dot notation for keys
36
+ t1 = Table[ :something => 50, :else => 100 ]
37
+ t1.something #=> 50
38
+ t1.something = 100
39
+ t1.something #=> 100
40
+ t1.some_new_key = "sdsdsd"
41
+ t1.some_new_key #=> "sdsdsd"
42
+
43
+ # as a combination of an array and a hash
44
+ t2 = Table[ 1, 2, 3, 4, 5, { :a => 1000, :b => 2000 }, 6, 7, { :c => 50, :d => 60 }, 8, 9 ]
45
+
46
+ # the size method returns the number of array values inside the table, this is identical
47
+ # to lua's length operator (#table)
48
+ t2.size #=> 9
49
+
50
+ t2.each_pair { | k, v | print k } #=> abcd
51
+
52
+ # tables can be concatenated
53
+ t3 = t1 + t2
54
+ t3.pairs #=> { :something => 50, :else => 100, :a => 1000, :b => 2000, :c => 50, :d => 60 }
55
+ t3.to_a #=> [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
56
+ t3.inject { |sum, i | sum + i } #=> 45
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.version = "0.1.0"
8
+ gem.name = "ruby-tables"
9
+ gem.summary = %Q{Ruby implementation of lua tables}
10
+ gem.description = %Q{A table data structure implemented in ruby}
11
+ gem.email = "nick.loves.rails@gmail.com"
12
+ gem.homepage = "http://github.com/Abica/ruby-tables"
13
+ gem.authors = [ "Nicholas Wright" ]
14
+ gem.add_development_dependency "rspec", ">= 1.2.2"
15
+ gem.has_rdoc = true
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+ task :default => :spec
23
+
24
+ require 'rake/rdoctask'
25
+ Rake::RDocTask.new do |rdoc|
26
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
27
+
28
+ rdoc.rdoc_dir = 'rdoc'
29
+ rdoc.title = "ruby-tables #{version}"
30
+ rdoc.rdoc_files.include('README*')
31
+ rdoc.rdoc_files.include('lib/**/*.rb')
32
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,193 @@
1
+ # Implements a table data structure
2
+ class Table
3
+ include Enumerable
4
+
5
+ # takes a comma separated list of arrays and hashes and returns a table
6
+ #
7
+ # example:
8
+ # Table[ 1, 2, 3, 4, { :a => 3, :b => 5 }, 7, 8, { :c => 33 } ]
9
+ def self.[] *args
10
+ new *args
11
+ end
12
+
13
+ def initialize *args
14
+ @values = []
15
+ @records = {}
16
+ process *args
17
+ end
18
+
19
+ # returns the value corresponding to the index or key
20
+ #
21
+ # t = Table[ 1, 2, "string", { :a => 4, :b => 5 }, 3, 4 ]
22
+ # t[ 2 ] #=> "string"
23
+ # t[ :a ] #=> 4
24
+ #
25
+ # symbolized keys are also accessible via dot notation:
26
+ #
27
+ # t.a #=> 4
28
+ # t.b #=> 5
29
+ def [] key
30
+ if key.is_a? Integer
31
+ @values[ key ]
32
+ else
33
+ @records[ key ]
34
+ end
35
+ end
36
+
37
+ # updates the value for a given key or index
38
+ # if no entry exists for the given key or index then one is created
39
+ #
40
+ # t = Table[ :a => "abcde", :b => 44332211 ]
41
+ # t[ :a ] = 43
42
+ # t[ :a ] #=> 43
43
+ # t[ 0 ] = 54
44
+ # t.first #=> 54
45
+ #
46
+ # note that like an array, if you insert a value into a table at an
47
+ # index that doesn't yet exist, any gaps will be filled in with nil
48
+ # such as:
49
+ #
50
+ # t[ 5 ] = 100
51
+ # t.to_a #=> [ 54, nil, nil, nil, 100 ]
52
+ #
53
+ # symbolized keys also have setters so that you can use dot notation:
54
+ #
55
+ # t.a = "bbcec"
56
+ # t.a #=> "bbcec"
57
+ def []= key, value
58
+ if key.is_a? Integer
59
+ @values[ key ] = value
60
+ else
61
+ process_hash key => value
62
+ end
63
+ end
64
+
65
+ # add a hash or value to this table
66
+ #
67
+ # t = Table[ 1, 2, 3 ]
68
+ # t << { :a => 4, :b => 4 }
69
+ def << arg
70
+ process arg
71
+ end
72
+
73
+ # combines 2 tables
74
+ #
75
+ # Table[ :a => 4, :b => 5 ] + Table[ 1, 2, 3, 4, { :c => 4 } ]
76
+ def + other
77
+ values = self.to_a + other.to_a
78
+ Table[ self.pairs, other.pairs, *values ]
79
+ end
80
+
81
+ # returns the first non pair item in the table
82
+ #
83
+ # t = Table[ { :a => 4 }, 1, 2, 3, 4, { :b => 4, :c => 23 } ]
84
+ # t.first #=> 1
85
+ def first
86
+ @values.first
87
+ end
88
+
89
+ # returns the last non pair item in the table
90
+ #
91
+ # t = Table[ { :a => 4 }, 1, 2, 3, 4, { :b => 4, :c => 23 } ]
92
+ # t.last #=> 4
93
+ def last
94
+ @values.last
95
+ end
96
+
97
+ # returns the length of all integer indexes
98
+ #
99
+ # t = Table[ 1, 2, { :b => 4 }, 3, 4 ]
100
+ # t.size #=> 4
101
+ def size
102
+ @values.size
103
+ end
104
+
105
+ alias length size
106
+
107
+ # iterate through each of the array values
108
+ def each &block
109
+ @values.each &block
110
+ end
111
+
112
+ # sort the array values
113
+ #
114
+ # t = Table[ 2, 23, 54, { :a => 4 }, 49 ]
115
+ # t.sort #=> [ 2, 23, 49, 54 ]
116
+ def sort &block
117
+ @values.sort &block
118
+ end
119
+
120
+ # iterate through the key => value pairs in the table
121
+ def each_pair &block
122
+ @records.each_pair &block
123
+ end
124
+
125
+ # iterate through the hash keys in the table
126
+ def each_key &block
127
+ @records.each_key &block
128
+ end
129
+
130
+ # returns a hash of all key => value pairs inside the table
131
+ #
132
+ # t = Table[ 1, { :a => 4 }, 2, { :b => 543 } ]
133
+ # t.pairs #=> { :a => 4, :b => 543 }
134
+ def pairs
135
+ @records
136
+ end
137
+
138
+ # return an array of all hash keys in the table
139
+ #
140
+ # t = Table[ 1, 2, { :a => 55, :b => 77 }, 3, { :c => 22 } ]
141
+ # t.keys #=> [ :a, :b, :c ]
142
+ def keys
143
+ @records.keys
144
+ end
145
+
146
+ # returns an array of all hash values in the table
147
+ #
148
+ # t = Table[ 1, 2, { :a => 55, :b => 77 }, 3, { :c => 22 } ]
149
+ # t.values #=> [ 55, 77, 22 ]
150
+ def values
151
+ @records.values
152
+ end
153
+
154
+ private
155
+ def process *args
156
+ args.each do | arg |
157
+ if arg.is_a? Hash
158
+ process_hash arg
159
+ else
160
+ @values << arg
161
+ end
162
+ end
163
+ end
164
+
165
+ def process_hash hsh
166
+ hsh.each do | key, value |
167
+ key = [ key ] if key.is_a? Integer
168
+ @records[ key ] = value
169
+
170
+ next unless key.is_a? Symbol
171
+ next if respond_to? key and respond_to? "#{ key }="
172
+
173
+ instance_eval <<-EOM
174
+ def #{ key }
175
+ @records[ :#{ key } ]
176
+ end
177
+
178
+ def #{ key }= value
179
+ @records[ :#{ key } ] = value
180
+ end
181
+ EOM
182
+ end
183
+ end
184
+
185
+ # if an accessor is called that doesn't exist, the key => value
186
+ # are added into the table
187
+ def method_missing meth_id, *args
188
+ name = meth_id.id2name
189
+ if key = name[ /(\w+)=/, 1 ]
190
+ process_hash key.to_sym => args.first
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,51 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{ruby-tables}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Nicholas Wright"]
12
+ s.date = %q{2010-02-13}
13
+ s.description = %q{A table data structure implemented in ruby}
14
+ s.email = %q{nick.loves.rails@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "README.rdoc",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "lib/table.rb",
24
+ "ruby-tables.gemspec",
25
+ "spec/spec_helper.rb",
26
+ "spec/table_spec.rb"
27
+ ]
28
+ s.homepage = %q{http://github.com/Abica/ruby-tables}
29
+ s.rdoc_options = ["--charset=UTF-8"]
30
+ s.require_paths = ["lib"]
31
+ s.rubygems_version = %q{1.3.5}
32
+ s.summary = %q{Ruby implementation of lua tables}
33
+ s.test_files = [
34
+ "spec/spec_helper.rb",
35
+ "spec/table_spec.rb"
36
+ ]
37
+
38
+ if s.respond_to? :specification_version then
39
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
40
+ s.specification_version = 3
41
+
42
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
43
+ s.add_development_dependency(%q<rspec>, [">= 1.2.2"])
44
+ else
45
+ s.add_dependency(%q<rspec>, [">= 1.2.2"])
46
+ end
47
+ else
48
+ s.add_dependency(%q<rspec>, [">= 1.2.2"])
49
+ end
50
+ end
51
+
@@ -0,0 +1,4 @@
1
+ require File.join( File.dirname( __FILE__ ), "..", "lib", "table" )
2
+
3
+ Spec::Runner.configure do | config |
4
+ end
@@ -0,0 +1,193 @@
1
+ require File.join( "spec", "spec_helper" )
2
+
3
+ describe Table do
4
+ before :all do
5
+ @args = [ 1, 2, 3, 4, 5, { :k => 4 }, 7, 8, { :v => 10 } ]
6
+ @array_vals = @args.reject { | a | a.is_a? Hash }
7
+ @table = Table[ *@args ]
8
+ end
9
+
10
+ describe "[]" do
11
+ it "is a new Table instance" do
12
+ t = Table[ *@args ]
13
+
14
+ t.should be_a( Table )
15
+ end
16
+ end
17
+
18
+ describe "#self.[]" do
19
+ it "returns the value at index" do
20
+ @array_vals.each_with_index do | val, i |
21
+ @table[ i ].should == val
22
+ end
23
+ end
24
+
25
+ it "returns the value at key" do
26
+ @table[ :k ].should == @args[ 5 ][ :k ]
27
+ @table[ :v ].should == @args[ 8 ][ :v ]
28
+ end
29
+ end
30
+
31
+ describe "#[]=" do
32
+ it "creates a new value at index" do
33
+ i = 500
34
+ new_value = "something_new"
35
+ @table[ i ].should be_nil
36
+ @table[ i ] = new_value
37
+ @table[ i ].should == new_value
38
+ @table.size.should >= i
39
+ end
40
+
41
+ it "updates the value at index" do
42
+ i = 3
43
+ old_value = @args[ i ]
44
+ new_value = 34903489034
45
+ @table[ i ].should == old_value
46
+ @table[ i ] = new_value
47
+ @table[ i ].should == new_value
48
+ end
49
+
50
+ it "creates a new value for key" do
51
+ key = :something_long_and_fake
52
+ new_value = 0b0110
53
+ @table[ key ].should be_nil
54
+ @table[ key ] = new_value
55
+ @table[ key ].should == new_value
56
+ end
57
+
58
+ it "updates the value for key" do
59
+ key = :v
60
+ old_value = @args[ 8 ][ key ]
61
+ new_value = 50000000
62
+
63
+ @table[ key ].should == old_value
64
+ @table[ key ] = new_value
65
+
66
+ @table[ key ].should == new_value
67
+ end
68
+ end
69
+
70
+ describe "#<<" do
71
+ it "pushes an argument onto the table" do
72
+ vals = [ 4000, [ 5, 0, 0, 0 ], "6000" ]
73
+ vals.each do | val |
74
+ @table << val
75
+ @table.last.should == val
76
+ end
77
+
78
+ hsh = { :this => 1, :was => 2, :added => 3 }
79
+ @table << hsh
80
+ hsh.each do | k, v |
81
+ @table[ k ].should == v
82
+ end
83
+ end
84
+ end
85
+
86
+ describe "#+" do
87
+ before :all do
88
+ @t1 = Table[ 1, 2, 3, { :a => 5, :b => 6 } ]
89
+ @t2 = Table[ 4, 5, { :c => 7, :d => 8 }, 6 ]
90
+ @t3 = @t1 + @t2
91
+ end
92
+
93
+ it "should combine 2 tables together" do
94
+ @t3.to_a.should == [ 1, 2, 3, 4, 5, 6 ]
95
+ pairs = @t3.pairs
96
+ [ :a, :b, :c, :d ].each do | key |
97
+ pairs.should have_key( key )
98
+ end
99
+ end
100
+ end
101
+
102
+ describe "#first" do
103
+ it "should return the first array element" do
104
+ t = Table[ *50..80 ]
105
+ t.first.should == 50
106
+
107
+ t = Table[ :a => 4, :b => 5, :c => 6 ]
108
+ t.first.should be_nil
109
+ end
110
+ end
111
+
112
+ describe "#last" do
113
+ it "should return the last array element" do
114
+ t = Table[ *50..80 ]
115
+ t.last.should == 80
116
+
117
+ t = Table[ :a => 4, :b => 5, :c => 6 ]
118
+ t.last.should be_nil
119
+
120
+ t = Table[ 1, 2, 3, { :a => 4, :b => 5, :c => 6 }, 600, 700, 800 ]
121
+ t.last.should == 800
122
+ end
123
+ end
124
+
125
+ describe "#size" do
126
+ it "should return the number of array elements in the table" do
127
+ @table.size.should == @array_vals.size
128
+ end
129
+
130
+ it "should be the same as length" do
131
+ @table.size.should == @table.length
132
+ end
133
+ end
134
+
135
+ describe "#sort" do
136
+ it "returns a sorted array" do
137
+ rand_vals = @array_vals.sort_by { rand }
138
+ sorted_vals = rand_vals.sort
139
+
140
+ t = Table[ *rand_vals ]
141
+ t.to_a.should_not == sorted_vals
142
+ t.sort.should == sorted_vals
143
+ end
144
+ end
145
+
146
+ describe "#pairs" do
147
+ it "returns a hash of all of the key => value pairs" do
148
+ pairs = @table.pairs
149
+ [ :k, :v ].each do | key |
150
+ pairs.should have_key( key )
151
+ end
152
+ end
153
+ end
154
+
155
+ describe "#keys" do
156
+ it "returns an array of all hash keys" do
157
+ pairs = @table.pairs
158
+ [ :k, :v ].each do | key |
159
+ pairs.should have_key( key )
160
+ end
161
+ end
162
+ end
163
+
164
+ describe "#values" do
165
+ it "returns an array of all hash values" do
166
+ @table.values.sort.should == [ 4, 10 ]
167
+ end
168
+ end
169
+
170
+ describe "setters for hash keys" do
171
+ it "should add a key if one doesn't exist" do
172
+ key = :super_long_key_name
173
+ meth_name = "#{ key }="
174
+ value = 349348908340
175
+ @table.should_not respond_to( meth_name )
176
+ @table.send meth_name, value
177
+ @table.should respond_to( meth_name )
178
+ @table[ key ].should == value
179
+ end
180
+
181
+ it "should override an existing key" do
182
+ @table.v.should == 10
183
+ @table.v = 50
184
+ @table.v.should == 50
185
+ end
186
+ end
187
+
188
+ describe "getters for hash keys" do
189
+ it "returns the value for a key" do
190
+ @table.v.should == 10
191
+ end
192
+ end
193
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-tables
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nicholas Wright
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-13 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.2
24
+ version:
25
+ description: A table data structure implemented in ruby
26
+ email: nick.loves.rails@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.rdoc
33
+ files:
34
+ - .gitignore
35
+ - README.rdoc
36
+ - Rakefile
37
+ - VERSION
38
+ - lib/table.rb
39
+ - ruby-tables.gemspec
40
+ - spec/spec_helper.rb
41
+ - spec/table_spec.rb
42
+ has_rdoc: true
43
+ homepage: http://github.com/Abica/ruby-tables
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --charset=UTF-8
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.3.5
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: Ruby implementation of lua tables
70
+ test_files:
71
+ - spec/spec_helper.rb
72
+ - spec/table_spec.rb