space_cadet 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []