space_cadet 0.8.1

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,4 @@
1
+ Gemfile.lock
2
+ *.gem
3
+ doc/
4
+ tmp/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in space_cadet.gemspec
4
+ gemspec
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Bardi Einarsson
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,112 @@
1
+ space\_cadet
2
+ ================
3
+
4
+ ## Summary
5
+
6
+ for space cadet augmented ActiveRecord::Base's, ruby ObjectSpace like object\_id's (called space\_id's) based on UUID's
7
+
8
+ ## Description
9
+
10
+ space\_cadet is a simple hack, for any ActiveRecord supported database, which provides a uuids table of distributable identities of space cadets -- ActiveRecord::Base instances which use the SpaceCadetWrapper. Each space cadet has by reference a space\_id unique in the set of all local space cadets; a space cadet's id is derived from its uuid - UUID's are by design universally distributable.
11
+
12
+ ## Usage
13
+
14
+ require 'space_cadet'
15
+
16
+ class ChessGame < ActiveRecord::Base
17
+
18
+ after_create SpaceCadetWrapper.new
19
+ before_destroy SpaceCadetWrapper.new # optional
20
+ ...
21
+
22
+ end # ChessGame
23
+
24
+ class MySpaceCadet < ActiveRecord::Base
25
+
26
+ after_create SpaceCadetWrapper.new
27
+ before_destroy SpaceCadetWrapper.new # optional
28
+ ...
29
+
30
+ end # MySpaceCadet
31
+
32
+ ChessGame instances are space cadets.
33
+
34
+ After ActiveRecord creates a ChessGame space cadet, it uses SecureRandom.uuid to generate a UUID. The lowest 31 bits of the UUID are used to make a space\_id.
35
+
36
+ The uuids table gains a chess\_games row as in:
37
+
38
+ id source_id source_name space_id ...uuid
39
+ 3 14 my_space_cadets 746042992 ...43e1ac77b670
40
+ 4 23 chess_games 569967860 ...35d4a1f904f4
41
+
42
+ ...uuid uuid
43
+ ...43e1ac77b670 7770a54c-7f08-4817-877e-43e1ac77b670
44
+ ...35d4a1f904f4 274ead56-7c8f-4c8d-ad21-35d4a1f904f4
45
+
46
+ The chess\_games table gains a row like:
47
+
48
+ id moves ambiguities move_number ...
49
+ 23 e2e4 1 ...
50
+
51
+ 569967860 == 0x21f904f4 # the 31 low order bits of the UUID
52
+
53
+ The result is that space\_id 569967860 is guaranteed to be unique for all space cadets i.e. ChessGame instances, MySpaceCadet instances and other space cadets. Note in the rare event that there is a duplicate id conflict in uuids, a new UUID is tried.
54
+
55
+ # space cadet's space id
56
+ my_space_cadet = ... # created MySpaceCadet instance
57
+ t = 'my_space_cadets'
58
+ id = my_space_cadet.id
59
+ u = SpaceCadet::Uuid.find_by_source_name_and_source_id(t, id)
60
+ space_id = u.space_id # my_space_cadet's space_id
61
+ uuid = u.uuid # my_space_cadet's uuid
62
+
63
+ # chess game from uuid and space_id
64
+ uuid = '274ead56-7c8f-4c8d-ad21-35d4a1f904f4'
65
+ space_id_calculator = Object.new.extend SpaceCadetSpaceId
66
+ # 569967860 == 0x21f904f4 # the 31 low order bits of the UUID
67
+ space_id = space_id_calculator.space_id_from_uuid uuid, 31
68
+ space_cadet_ref = SpaceCadet::Uuid.find_by_space_id space_id
69
+ source_id = space_cadet_ref.source_id # 23
70
+ space_cadet_source_name = space_cadet_ref.source_name # 'chess_games'
71
+ chess_game_class = <some function> space_cadet_source_name
72
+ chess_game = chess_game_class.find(source_id)
73
+ 'e2e4' == chess_game.moves # true
74
+
75
+ ## Requirements
76
+
77
+ Most likely any recent version of 1.9 ruby works.
78
+
79
+ Most likely any database gem supported by activerecord works.
80
+
81
+ Most likely any version of the activerecord gem which can use the given database gem and can be used with require "active\_record" works.
82
+
83
+ ## Test with rspec ~> 2.11, rspec -fd
84
+
85
+ The specs assume that the connection url in spec/support/space\_cadet.rb works.
86
+
87
+ The specs assume that the uuids table exists in the database.
88
+
89
+ The specs assume that the chess\_games table exists in the database.
90
+
91
+ The specs do not update the database (transactions with rollback).
92
+
93
+ Note, to prepare the database for testing:
94
+
95
+ irb prompt> load 'spec/support/space_cadet.rb'
96
+ irb prompt> up
97
+ irb prompt> exit
98
+
99
+ The author uses DbVisualizer 9.0.5 and irb to try out the space cadets.
100
+
101
+ Note, to find the gem installation directory:
102
+
103
+ irb prompt> require 'space_cadet_wrapper'
104
+ irb prompt> $".grep(/space_cadet/)[0]
105
+ irb prompt> exit
106
+
107
+ ## License
108
+
109
+ Copyright (c) 2013 Bardi Einarsson. Released under the MIT License. See the [LICENSE][license] file for further details.
110
+
111
+ [license]: https://github.com/bardibardi/space_cadet/blob/master/LICENSE.md
112
+
@@ -0,0 +1,22 @@
1
+ require_relative 'space_cadet_any_db_uuid'
2
+
3
+ class SpaceCadetWrapper
4
+
5
+ include SpaceCadetUuid
6
+
7
+ ID_BIT_COUNT = 31
8
+
9
+ def after_create record
10
+ source_id = record.id
11
+ source_name = record.class.table_name
12
+ uuid_create SpaceCadet::Uuid, source_id, source_name, ID_BIT_COUNT
13
+ end
14
+
15
+ def before_destroy record
16
+ u = SpaceCadet::Uuid.find_by_source_name_and_source_id(
17
+ record.class.table_name, record.id)
18
+ SpaceCadet::Uuid.delete u.id
19
+ end
20
+
21
+ end # SpaceCadetWrapper
22
+
@@ -0,0 +1,41 @@
1
+ # needs
2
+ # space_id = space_id_from_uuid uuid, id_bit_count
3
+
4
+ require 'securerandom'
5
+ require 'active_record'
6
+
7
+ module SpaceCadetActiveRecordUuid
8
+
9
+ def add_uuid uuid_class, source_id, source_name, space_id, uuid
10
+ uuid_class.create! do |u|
11
+ u.source_id = source_id
12
+ u.source_name = source_name
13
+ u.space_id = space_id
14
+ u.uuid = uuid
15
+ end
16
+ end
17
+
18
+ def space_id_add_uuid uuid_class, source_id, source_name, id_bit_count
19
+ uuid = SecureRandom.uuid
20
+ space_id = space_id_from_uuid uuid, id_bit_count
21
+ record = nil
22
+ begin
23
+ record = add_uuid uuid_class, source_id, source_name, space_id, uuid
24
+ rescue
25
+ record = nil
26
+ end
27
+ record
28
+ end
29
+
30
+ ID_RETRY_COUNT = 10
31
+
32
+ def uuid_create uuid_class, source_id, source_name, id_bit_count
33
+ record = nil
34
+ retry_count = 0
35
+ while !record && retry_count < ID_RETRY_COUNT do
36
+ record = space_id_add_uuid uuid_class, source_id, source_name, id_bit_count
37
+ end
38
+ end
39
+
40
+ end # SpaceCadetActiveRecordUuid
41
+
@@ -0,0 +1,11 @@
1
+ require_relative 'space_cadet_uuid'
2
+ require_relative 'space_cadet_space_id'
3
+ require_relative 'space_cadet_active_record_uuid'
4
+
5
+ module SpaceCadetUuid
6
+
7
+ include SpaceCadetSpaceId
8
+ include SpaceCadetActiveRecordUuid
9
+
10
+ end
11
+
@@ -0,0 +1,30 @@
1
+ module SpaceCadetSpaceId
2
+
3
+ HEX_DIGIT ||= Hash[
4
+ '0', 0, '1', 1, '2', 2, '3', 3,
5
+ '4', 4, '5', 5, '6', 6, '7', 7,
6
+ '8', 8, '9', 9, 'a', 10, 'b', 11,
7
+ 'c', 12, 'd', 13, 'e', 14, 'f', 15
8
+ ].reduce({}, &->(h,p){h[p[0].getbyte(0)] = p[1];h})
9
+ def num_from_hex_string hex_string
10
+ hex_string.bytes.reduce(0, &->(num,b){num <<= 4;num += HEX_DIGIT[b]})
11
+ end
12
+
13
+ def high_order_bits_from_hex_string hex_string, bit_count
14
+ total_bit_count = hex_string.length << 2
15
+ num = num_from_hex_string hex_string
16
+ num >> (total_bit_count - bit_count)
17
+ end
18
+
19
+ def low_order_bits_from_hex_string hex_string, bit_count
20
+ num = num_from_hex_string hex_string
21
+ num & ((1 << bit_count) - 1)
22
+ end
23
+
24
+ def space_id_from_uuid uuid, id_bit_count
25
+ hex_string = uuid[24..-1]
26
+ low_order_bits_from_hex_string hex_string, id_bit_count
27
+ end
28
+
29
+ end # SpaceCadetSpaceId
30
+
@@ -0,0 +1,29 @@
1
+ require 'active_record'
2
+
3
+ module SpaceCadet
4
+
5
+ class UuidCore < ActiveRecord::Migration
6
+
7
+ def self.up
8
+ create_table :uuids do |t|
9
+ t.integer :source_id
10
+ t.string :source_name
11
+ t.integer :space_id
12
+ t.string :uuid
13
+ end
14
+
15
+ add_index :uuids, :space_id, unique: true
16
+ add_index :uuids, [:source_name, :source_id], unique: true
17
+ end
18
+
19
+ def self.down
20
+ drop_table :uuids
21
+ end
22
+
23
+ end # UuidCore
24
+
25
+ class Uuid < ActiveRecord::Base
26
+ end # Uuid
27
+
28
+ end # SpaceCadet
29
+
@@ -0,0 +1,35 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'space_cadet'
3
+ s.version = '0.8.1'
4
+ s.date = '2013-03-24'
5
+ s.summary = "for space cadet augmented ActiveRecord::Base's, ruby ObjectSpace like object_id's (called space_id's) based on UUID's"
6
+ s.description = "space_cadet is a simple hack, for any ActiveRecord supported database, which provides a uuids table of distributable identities of space cadets -- ActiveRecord::Base instances which use the SpaceCadetWrapper. Each space cadet has by reference a space_id unique in the set of all local space cadets; a space cadet's space_id is derived from its uuid - UUID's are by design universally distributable."
7
+
8
+ s.authors = ['Bardi Einarsson']
9
+ s.email = ['bardi@hotmail.com']
10
+ s.homepage = 'https://github.com/bardibardi/space_cadet'
11
+ s.required_ruby_version = '>= 1.9.2'
12
+ s.add_dependency('activerecord', '>= 3.0')
13
+ s.add_development_dependency('sqlite', '~> 1.3.3')
14
+ s.add_development_dependency('rspec', '~> 2.11')
15
+ s.requirements << 'most likely any version of the activerecord gem which can be used with require "active_record"'
16
+
17
+ s.files = %w(
18
+ .gitignore
19
+ Gemfile
20
+ LICENSE.md
21
+ README.md
22
+ space_cadet.gemspec
23
+ lib/space_cadet_active_record_uuid.rb
24
+ lib/space_cadet_any_db_uuid.rb
25
+ lib/space_cadet_uuid.rb
26
+ lib/space_cadet_space_id.rb
27
+ lib/space_cadet.rb
28
+ spec/space_cadet_spec.rb
29
+ spec/space_cadet_space_id_spec.rb
30
+ spec/support/ar_rspec.rb
31
+ spec/support/no_should_rspec.rb
32
+ spec/support/space_cadet.rb
33
+ )
34
+ end
35
+
@@ -0,0 +1,33 @@
1
+ require 'support/no_should_rspec'
2
+ require 'space_cadet_space_id'
3
+
4
+ $idcalc = Object.new.extend SpaceCadetSpaceId
5
+
6
+ describe SpaceCadetSpaceId do
7
+
8
+ it "should convert hex chars to digits" do
9
+ digits = "abcef" * 10
10
+ eval_value = eval("0x" + digits)
11
+ value = $idcalc.num_from_hex_string digits
12
+ expect(value).to eq(eval_value)
13
+ end
14
+
15
+ it "should get high order bits" do
16
+ digits = "abcef" * 10
17
+ value = $idcalc.high_order_bits_from_hex_string digits, 3
18
+ expect(value).to eq(5)
19
+ end
20
+
21
+ it "should get low order bits" do
22
+ digits = "abcef" * 10
23
+ value = $idcalc.low_order_bits_from_hex_string digits, 3
24
+ expect(value).to eq(7)
25
+ end
26
+
27
+ it "should get uuid low order bits" do
28
+ uuid = "ef53c3f1-9c4f-46db-9f6c-02c7402ef24a"
29
+ value = $idcalc.space_id_from_uuid uuid, 3
30
+ expect(value).to eq(2)
31
+ end
32
+
33
+ end
@@ -0,0 +1,49 @@
1
+ require_relative 'support/ar_rspec'
2
+ require_relative 'support/space_cadet'
3
+ require 'securerandom'
4
+
5
+ describe SpaceCadet::Uuid do
6
+
7
+ it "should be created" do
8
+ id, _ = add_chess_game 'e2e4', ''
9
+ u = SpaceCadet::Uuid.find_by_source_name_and_source_id(
10
+ 'chess_games', id)
11
+ expect(id).to eq(u.source_id)
12
+ end
13
+
14
+ it "should have unique space_id" do
15
+ duplicate_id, chess_game = add_chess_game 'e2e4', ''
16
+ u = SpaceCadet::Uuid.find_by_source_name_and_source_id(
17
+ 'chess_games', duplicate_id)
18
+ duplicate_uuid = u.uuid
19
+ scsi = Object.new.extend SpaceCadetSpaceId
20
+ duplicate_space_id = scsi.space_id_from_uuid duplicate_uuid, 31
21
+ exception_thrown = nil
22
+ begin
23
+ chess_game.add_uuid(SpaceCadet::Uuid.class, duplicate_id + 1,
24
+ 'chess_games', duplicate_space_id, duplicate_uuid)
25
+ rescue
26
+ exception_thrown = true
27
+ end
28
+ expect(exception_thrown).to eq(true)
29
+ end
30
+
31
+ it "should be deleted when parent is destroyed" do
32
+ id, chess_game = add_chess_game 'e2e4', ''
33
+ u = SpaceCadet::Uuid.find_by_source_name_and_source_id(
34
+ 'chess_games', id)
35
+ expect(id).to eq(u.source_id)
36
+ chess_game.class.destroy(id)
37
+ exception_thrown = nil
38
+ begin
39
+ u = SpaceCadet::Uuid.find_by_source_name_and_source_id(
40
+ 'chess_games', id)
41
+ raise 'no uuid' unless u
42
+ rescue
43
+ exception_thrown = true
44
+ end
45
+ expect(exception_thrown).to eq(true)
46
+ end
47
+
48
+ end
49
+
@@ -0,0 +1,36 @@
1
+ # NB: http://iain.nl/testing-activerecord-in-isolation
2
+ # NB: require 'support/ar_rspec'
3
+ require_relative 'no_should_rspec'
4
+ require 'active_record'
5
+
6
+ module ActiveModel::Validations
7
+ # Extension to enhance `should have` on AR Model instances. Calls
8
+ # model.valid? in order to prepare the object's errors object.
9
+ #
10
+ # You can also use this to specify the content of the error messages.
11
+ #
12
+ # @example
13
+ #
14
+ # model.should have(:no).errors_on(:attribute)
15
+ # model.should have(1).error_on(:attribute)
16
+ # model.should have(n).errors_on(:attribute)
17
+ #
18
+ # model.errors_on(:attribute).should include("can't be blank")
19
+ def errors_on(attribute)
20
+ self.valid?
21
+ [self.errors[attribute]].flatten.compact
22
+ end
23
+ alias :error_on :errors_on
24
+ end
25
+
26
+ RSpec.configure do |config|
27
+
28
+ config.around do |example|
29
+ ActiveRecord::Base.transaction do
30
+ example.run
31
+ raise ActiveRecord::Rollback
32
+ end
33
+ end
34
+
35
+ end
36
+
@@ -0,0 +1,9 @@
1
+ RSpec.configure do |config|
2
+
3
+ # rspec 2.11 turn off should monkey patching
4
+ config.expect_with :rspec do |c|
5
+ c.syntax = :expect
6
+ end
7
+
8
+ end
9
+
@@ -0,0 +1,68 @@
1
+ def l
2
+ me = File.expand_path File.basename(__FILE__), File.dirname(__FILE__)
3
+ result = load me
4
+ [result, me]
5
+ end
6
+
7
+ require_relative '../../lib/space_cadet'
8
+
9
+ POSTGRESQL_URL ||= "postgres://postgres:postgres@localhost/postgres"
10
+
11
+ CONNECTION_POOL ||= ActiveRecord::Base.establish_connection POSTGRESQL_URL
12
+
13
+ END { CONNECTION_POOL.disconnect! }
14
+
15
+ class ChessGameCore < ActiveRecord::Migration
16
+
17
+ def self.up
18
+ create_table :chess_games do |t|
19
+ t.string :moves
20
+ t.string :ambiguities
21
+ t.integer :move_number
22
+ t.integer :is_whites_move
23
+ t.string :position
24
+ end
25
+ end
26
+
27
+ def self.down
28
+ drop_table :chess_games
29
+ end
30
+
31
+ end # ChessGameCore
32
+
33
+ class ChessGame < ActiveRecord::Base
34
+
35
+ after_create SpaceCadetWrapper.new
36
+ before_destroy SpaceCadetWrapper.new
37
+
38
+ end # ChessGame
39
+
40
+ START_POSITION ||=
41
+ "a8brb8bnc8bbd8bqe8bkf8bbg8bnh8br" +
42
+ "a7bpb7bpc7bpd7bpe7bpf7bpg7bph7bp" +
43
+ "a2wpb2wpc2wpd2wpe2wpf2wpg2wph2wp" +
44
+ "a1wrb1wnc1wbd1wqe1wkf1wbg1wnh1wr"
45
+
46
+ def add_chess_game moves, ambiguities
47
+ record = nil
48
+ ChessGame.create! do |g|
49
+ g.moves = moves
50
+ g.ambiguities = ambiguities
51
+ g.move_number = 1
52
+ g.is_whites_move = 1
53
+ g.position = START_POSITION
54
+ record = g
55
+ end
56
+ [record.id, record]
57
+ end
58
+
59
+ def up
60
+ SpaceCadet::UuidCore.up
61
+ ChessGameCore.up
62
+ end
63
+
64
+ def down
65
+ ChessGameCore.down
66
+ SpaceCadet::UuidCore.down
67
+ end
68
+
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: space_cadet
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Bardi Einarsson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: sqlite
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 1.3.3
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.3.3
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '2.11'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '2.11'
62
+ description: space_cadet is a simple hack, for any ActiveRecord supported database,
63
+ which provides a uuids table of distributable identities of space cadets -- ActiveRecord::Base
64
+ instances which use the SpaceCadetWrapper. Each space cadet has by reference a space_id
65
+ unique in the set of all local space cadets; a space cadet's space_id is derived
66
+ from its uuid - UUID's are by design universally distributable.
67
+ email:
68
+ - bardi@hotmail.com
69
+ executables: []
70
+ extensions: []
71
+ extra_rdoc_files: []
72
+ files:
73
+ - .gitignore
74
+ - Gemfile
75
+ - LICENSE.md
76
+ - README.md
77
+ - space_cadet.gemspec
78
+ - lib/space_cadet_active_record_uuid.rb
79
+ - lib/space_cadet_any_db_uuid.rb
80
+ - lib/space_cadet_uuid.rb
81
+ - lib/space_cadet_space_id.rb
82
+ - lib/space_cadet.rb
83
+ - spec/space_cadet_spec.rb
84
+ - spec/space_cadet_space_id_spec.rb
85
+ - spec/support/ar_rspec.rb
86
+ - spec/support/no_should_rspec.rb
87
+ - spec/support/space_cadet.rb
88
+ homepage: https://github.com/bardibardi/space_cadet
89
+ licenses: []
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: 1.9.2
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements:
107
+ - most likely any version of the activerecord gem which can be used with require "active_record"
108
+ rubyforge_project:
109
+ rubygems_version: 1.8.25
110
+ signing_key:
111
+ specification_version: 3
112
+ summary: for space cadet augmented ActiveRecord::Base's, ruby ObjectSpace like object_id's
113
+ (called space_id's) based on UUID's
114
+ test_files: []