characterizable 0.0.17 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/characterizable.gemspec +9 -3
- data/lib/characterizable.rb +11 -182
- data/lib/characterizable/base.rb +32 -0
- data/lib/characterizable/better_hash.rb +39 -0
- data/lib/characterizable/characteristic.rb +80 -0
- data/lib/characterizable/snapshot.rb +51 -0
- data/test/characterizable/test_characteristic.rb +23 -0
- data/test/test_characterizable.rb +14 -5
- metadata +9 -9
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/characterizable.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{characterizable}
|
8
|
-
s.version = "0.0
|
8
|
+
s.version = "0.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Andy Rossmeissl", "Seamus Abshere"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-11-03}
|
13
13
|
s.description = %q{Characterize the relationship between "attributes" (getters/setters) of instances of a class}
|
14
14
|
s.email = %q{seamus@abshere.net}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -25,6 +25,11 @@ Gem::Specification.new do |s|
|
|
25
25
|
"VERSION",
|
26
26
|
"characterizable.gemspec",
|
27
27
|
"lib/characterizable.rb",
|
28
|
+
"lib/characterizable/base.rb",
|
29
|
+
"lib/characterizable/better_hash.rb",
|
30
|
+
"lib/characterizable/characteristic.rb",
|
31
|
+
"lib/characterizable/snapshot.rb",
|
32
|
+
"test/characterizable/test_characteristic.rb",
|
28
33
|
"test/helper.rb",
|
29
34
|
"test/test_characterizable.rb"
|
30
35
|
]
|
@@ -34,7 +39,8 @@ Gem::Specification.new do |s|
|
|
34
39
|
s.rubygems_version = %q{1.3.7}
|
35
40
|
s.summary = %q{Characterize instances of a class}
|
36
41
|
s.test_files = [
|
37
|
-
"test/
|
42
|
+
"test/characterizable/test_characteristic.rb",
|
43
|
+
"test/helper.rb",
|
38
44
|
"test/test_characterizable.rb"
|
39
45
|
]
|
40
46
|
|
data/lib/characterizable.rb
CHANGED
@@ -12,6 +12,12 @@ require 'active_support/version'
|
|
12
12
|
require active_support_3_requirement
|
13
13
|
end if ActiveSupport::VERSION::MAJOR == 3
|
14
14
|
|
15
|
+
$:.unshift File.dirname(__FILE__)
|
16
|
+
require 'characterizable/base'
|
17
|
+
require 'characterizable/better_hash'
|
18
|
+
require 'characterizable/characteristic'
|
19
|
+
require 'characterizable/snapshot'
|
20
|
+
|
15
21
|
module Characterizable
|
16
22
|
def self.included(klass)
|
17
23
|
klass.cattr_accessor :characterizable_base
|
@@ -25,93 +31,10 @@ module Characterizable
|
|
25
31
|
def expire_snapshot!
|
26
32
|
@_characteristics = nil
|
27
33
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
def to_hash
|
33
|
-
Hash.new.replace self
|
34
|
-
end
|
35
|
-
def as_json(*)
|
36
|
-
to_hash
|
37
|
-
end
|
38
|
-
def reject(&block)
|
39
|
-
inject(Characterizable::BetterHash.new) do |memo, ary|
|
40
|
-
unless block.call(*ary)
|
41
|
-
memo[ary[0]] = ary[1]
|
42
|
-
end
|
43
|
-
memo
|
44
|
-
end
|
45
|
-
end
|
46
|
-
def select(&block)
|
47
|
-
inject(Characterizable::BetterHash.new) do |memo, ary|
|
48
|
-
if block.call(*ary)
|
49
|
-
memo[ary[0]] = ary[1]
|
50
|
-
end
|
51
|
-
memo
|
52
|
-
end
|
53
|
-
end
|
54
|
-
# I need this because otherwise it will try to do self.class.new on subclasses
|
55
|
-
# which would get "0 for 1" arguments error with Snapshot, among other things
|
56
|
-
def slice(*keep)
|
57
|
-
inject(Characterizable::BetterHash.new) do |memo, ary|
|
58
|
-
if keep.include?(ary[0])
|
59
|
-
memo[ary[0]] = ary[1]
|
60
|
-
end
|
61
|
-
memo
|
62
|
-
end
|
63
|
-
end
|
64
|
-
# end
|
65
|
-
end
|
66
|
-
|
67
|
-
class Snapshot < BetterHash
|
68
|
-
attr_reader :universe
|
69
|
-
def initialize(universe)
|
70
|
-
@universe = universe
|
71
|
-
_take_snapshot
|
72
|
-
end
|
73
|
-
def _take_snapshot
|
74
|
-
universe.characterizable_base.characteristics.each do |_, c|
|
75
|
-
if c.known?(universe)
|
76
|
-
if c.effective?(universe)
|
77
|
-
self[c.name] = c.value(universe)
|
78
|
-
elsif c.trumped?(universe)
|
79
|
-
trumped_keys.push c.name
|
80
|
-
elsif !c.revealed?(universe)
|
81
|
-
wasted_keys.push c.name
|
82
|
-
lacking_keys.push c.prerequisite
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
def []=(key, value)
|
88
|
-
universe.expire_snapshot!
|
89
|
-
super
|
90
|
-
end
|
91
|
-
def wasted_keys
|
92
|
-
@wasted_keys ||= Array.new
|
93
|
-
end
|
94
|
-
def trumped_keys
|
95
|
-
@trumped_keys ||= Array.new
|
96
|
-
end
|
97
|
-
def lacking_keys
|
98
|
-
@lacking_keys ||= Array.new
|
99
|
-
end
|
100
|
-
def effective
|
101
|
-
universe.characterizable_base.characteristics.select { |_, c| c.effective?(self) }
|
102
|
-
end
|
103
|
-
def potential
|
104
|
-
universe.characterizable_base.characteristics.select { |_, c| c.potential?(self) }
|
105
|
-
end
|
106
|
-
def wasted
|
107
|
-
universe.characterizable_base.characteristics.slice(*wasted_keys)
|
108
|
-
end
|
109
|
-
def lacking
|
110
|
-
universe.characterizable_base.characteristics.slice(*(lacking_keys - wasted_keys))
|
111
|
-
end
|
112
|
-
def trumped
|
113
|
-
universe.characterizable_base.characteristics.slice(*trumped_keys)
|
114
|
-
end
|
34
|
+
|
35
|
+
def display_characteristic(name)
|
36
|
+
characteristic = self.class.characteristics[name]
|
37
|
+
characteristic.display(characteristics) if characteristic
|
115
38
|
end
|
116
39
|
|
117
40
|
module ClassMethods
|
@@ -124,99 +47,5 @@ module Characterizable
|
|
124
47
|
end
|
125
48
|
end
|
126
49
|
|
127
|
-
class CharacteristicAlreadyDefined < ArgumentError
|
128
|
-
end
|
129
|
-
|
130
|
-
class Base
|
131
|
-
attr_reader :klass
|
132
|
-
def initialize(klass)
|
133
|
-
@klass = klass
|
134
|
-
end
|
135
|
-
def characteristics
|
136
|
-
@_characteristics ||= BetterHash.new
|
137
|
-
end
|
138
|
-
include Blockenspiel::DSL
|
139
|
-
def has(name, options = {}, &block)
|
140
|
-
raise CharacteristicAlreadyDefined, "The characteristic #{name} has already been defined on #{klass}!" if characteristics.has_key?(name)
|
141
|
-
characteristics[name] = Characteristic.new(self, name, options, &block)
|
142
|
-
begin
|
143
|
-
# quacks like an activemodel
|
144
|
-
klass.define_attribute_methods unless klass.respond_to?(:attribute_methods_generated?) and klass.attribute_methods_generated?
|
145
|
-
rescue
|
146
|
-
# for example, if a table doesn't exist... just ignore it
|
147
|
-
end
|
148
|
-
begin
|
149
|
-
klass.module_eval(%{
|
150
|
-
def #{name}_with_expire_snapshot=(new_#{name})
|
151
|
-
expire_snapshot!
|
152
|
-
self.#{name}_without_expire_snapshot = new_#{name}
|
153
|
-
end
|
154
|
-
alias_method_chain :#{name}=, :expire_snapshot
|
155
|
-
}, __FILE__, __LINE__) #if klass.instance_methods.include?("#{name}=")
|
156
|
-
rescue
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
class Characteristic
|
161
|
-
attr_reader :base
|
162
|
-
attr_reader :name
|
163
|
-
attr_reader :trumps
|
164
|
-
attr_reader :prerequisite
|
165
|
-
attr_reader :options
|
166
|
-
def initialize(base, name, options = {}, &block)
|
167
|
-
@base = base
|
168
|
-
@name = name
|
169
|
-
@trumps = Array.wrap options.delete(:trumps)
|
170
|
-
@prerequisite = options.delete(:prerequisite)
|
171
|
-
@options = options
|
172
|
-
Blockenspiel.invoke block, self if block_given?
|
173
|
-
end
|
174
|
-
def as_json(*)
|
175
|
-
{ :name => name, :trumps => trumps, :prerequisite => prerequisite, :options => options }
|
176
|
-
end
|
177
|
-
def inspect
|
178
|
-
"<Characterizable::Characteristic name=#{name.inspect} trumps=#{trumps.inspect} prerequisite=#{prerequisite.inspect} options=#{options.inspect}>"
|
179
|
-
end
|
180
|
-
def characteristics
|
181
|
-
base.characteristics
|
182
|
-
end
|
183
|
-
def value(universe)
|
184
|
-
case universe
|
185
|
-
when Hash
|
186
|
-
universe[name]
|
187
|
-
else
|
188
|
-
universe.send name if universe.respond_to?(name)
|
189
|
-
end
|
190
|
-
end
|
191
|
-
def known?(universe)
|
192
|
-
not value(universe).nil?
|
193
|
-
end
|
194
|
-
def potential?(universe)
|
195
|
-
not known?(universe) and revealed? universe and not trumped? universe
|
196
|
-
end
|
197
|
-
def effective?(universe, ignoring = nil)
|
198
|
-
known?(universe) and revealed? universe and not trumped? universe, ignoring
|
199
|
-
end
|
200
|
-
def trumped?(universe, ignoring = nil)
|
201
|
-
characteristics.each do |_, other|
|
202
|
-
if other.trumps.include? name and not ignoring == other.name
|
203
|
-
if trumps.include? other.name
|
204
|
-
# special case: mutual trumping. current characteristic is trumped if its friend is otherwise effective and it is not otherwise effective
|
205
|
-
return true if other.effective? universe, name and not effective? universe, other.name
|
206
|
-
else
|
207
|
-
return true if other.effective? universe
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
211
|
-
false
|
212
|
-
end
|
213
|
-
def revealed?(universe)
|
214
|
-
return true if prerequisite.nil?
|
215
|
-
characteristics[prerequisite].effective? universe
|
216
|
-
end
|
217
|
-
include Blockenspiel::DSL
|
218
|
-
def reveals(other_name, other_options = {}, &block)
|
219
|
-
base.has other_name, other_options.merge(:prerequisite => name), &block
|
220
|
-
end
|
221
|
-
end
|
50
|
+
class CharacteristicAlreadyDefined < ArgumentError; end
|
222
51
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Characterizable
|
2
|
+
class Base
|
3
|
+
attr_reader :klass
|
4
|
+
def initialize(klass)
|
5
|
+
@klass = klass
|
6
|
+
end
|
7
|
+
def characteristics
|
8
|
+
@_characteristics ||= BetterHash.new
|
9
|
+
end
|
10
|
+
include Blockenspiel::DSL
|
11
|
+
def has(name, options = {}, &block)
|
12
|
+
raise CharacteristicAlreadyDefined, "The characteristic #{name} has already been defined on #{klass}!" if characteristics.has_key?(name)
|
13
|
+
characteristics[name] = Characteristic.new(self, name, options, &block)
|
14
|
+
begin
|
15
|
+
# quacks like an activemodel
|
16
|
+
klass.define_attribute_methods unless klass.respond_to?(:attribute_methods_generated?) and klass.attribute_methods_generated?
|
17
|
+
rescue
|
18
|
+
# for example, if a table doesn't exist... just ignore it
|
19
|
+
end
|
20
|
+
begin
|
21
|
+
klass.module_eval(%{
|
22
|
+
def #{name}_with_expire_snapshot=(new_#{name})
|
23
|
+
expire_snapshot!
|
24
|
+
self.#{name}_without_expire_snapshot = new_#{name}
|
25
|
+
end
|
26
|
+
alias_method_chain :#{name}=, :expire_snapshot
|
27
|
+
}, __FILE__, __LINE__) #if klass.instance_methods.include?("#{name}=")
|
28
|
+
rescue
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Characterizable
|
2
|
+
class BetterHash < ::Hash
|
3
|
+
# In Ruby 1.9, running select/reject/etc. gives you back a hash
|
4
|
+
# if RUBY_VERSION < '1.9'
|
5
|
+
def to_hash
|
6
|
+
Hash.new.replace self
|
7
|
+
end
|
8
|
+
def as_json(*)
|
9
|
+
to_hash
|
10
|
+
end
|
11
|
+
def reject(&block)
|
12
|
+
inject(Characterizable::BetterHash.new) do |memo, ary|
|
13
|
+
unless block.call(*ary)
|
14
|
+
memo[ary[0]] = ary[1]
|
15
|
+
end
|
16
|
+
memo
|
17
|
+
end
|
18
|
+
end
|
19
|
+
def select(&block)
|
20
|
+
inject(Characterizable::BetterHash.new) do |memo, ary|
|
21
|
+
if block.call(*ary)
|
22
|
+
memo[ary[0]] = ary[1]
|
23
|
+
end
|
24
|
+
memo
|
25
|
+
end
|
26
|
+
end
|
27
|
+
# I need this because otherwise it will try to do self.class.new on subclasses
|
28
|
+
# which would get "0 for 1" arguments error with Snapshot, among other things
|
29
|
+
def slice(*keep)
|
30
|
+
inject(Characterizable::BetterHash.new) do |memo, ary|
|
31
|
+
if keep.include?(ary[0])
|
32
|
+
memo[ary[0]] = ary[1]
|
33
|
+
end
|
34
|
+
memo
|
35
|
+
end
|
36
|
+
end
|
37
|
+
# end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Characterizable
|
2
|
+
class Characteristic
|
3
|
+
attr_reader :base, :name, :trumps, :prerequisite, :display, :options
|
4
|
+
|
5
|
+
def initialize(base, name, options = {}, &block)
|
6
|
+
@base = base
|
7
|
+
@name = name
|
8
|
+
@trumps = Array.wrap options.delete(:trumps)
|
9
|
+
@prerequisite = options.delete(:prerequisite)
|
10
|
+
@display = options.delete(:display)
|
11
|
+
@options = options
|
12
|
+
Blockenspiel.invoke block, self if block_given?
|
13
|
+
end
|
14
|
+
|
15
|
+
def as_json(*)
|
16
|
+
{ :name => name, :trumps => trumps, :prerequisite => prerequisite, :options => options }
|
17
|
+
end
|
18
|
+
|
19
|
+
def inspect
|
20
|
+
"<Characterizable::Characteristic name=#{name.inspect} trumps=#{trumps.inspect} prerequisite=#{prerequisite.inspect} options=#{options.inspect}>"
|
21
|
+
end
|
22
|
+
|
23
|
+
def characteristics
|
24
|
+
base.characteristics
|
25
|
+
end
|
26
|
+
|
27
|
+
def value(universe)
|
28
|
+
case universe
|
29
|
+
when Hash
|
30
|
+
universe[name]
|
31
|
+
else
|
32
|
+
universe.send name if universe.respond_to?(name)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def display(universe)
|
37
|
+
@display.call(value(universe)) if @display
|
38
|
+
end
|
39
|
+
|
40
|
+
def known?(universe)
|
41
|
+
not value(universe).nil?
|
42
|
+
end
|
43
|
+
|
44
|
+
def potential?(universe)
|
45
|
+
not known?(universe) and revealed? universe and not trumped? universe
|
46
|
+
end
|
47
|
+
|
48
|
+
def effective?(universe, ignoring = nil)
|
49
|
+
known?(universe) and revealed? universe and not trumped? universe, ignoring
|
50
|
+
end
|
51
|
+
|
52
|
+
def trumped?(universe, ignoring = nil)
|
53
|
+
characteristics.each do |_, other|
|
54
|
+
if other.trumps.include? name and not ignoring == other.name
|
55
|
+
if trumps.include? other.name
|
56
|
+
# special case: mutual trumping. current characteristic is trumped if its friend is otherwise effective and it is not otherwise effective
|
57
|
+
return true if other.effective? universe, name and not effective? universe, other.name
|
58
|
+
else
|
59
|
+
return true if other.effective? universe
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
false
|
64
|
+
end
|
65
|
+
|
66
|
+
def revealed?(universe)
|
67
|
+
return true if prerequisite.nil?
|
68
|
+
characteristics[prerequisite].effective? universe
|
69
|
+
end
|
70
|
+
|
71
|
+
include Blockenspiel::DSL
|
72
|
+
def reveals(other_name, other_options = {}, &block)
|
73
|
+
base.has other_name, other_options.merge(:prerequisite => name), &block
|
74
|
+
end
|
75
|
+
|
76
|
+
def displays(&block)
|
77
|
+
@display = block
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Characterizable
|
2
|
+
class Snapshot < BetterHash
|
3
|
+
attr_reader :universe
|
4
|
+
def initialize(universe)
|
5
|
+
@universe = universe
|
6
|
+
_take_snapshot
|
7
|
+
end
|
8
|
+
def _take_snapshot
|
9
|
+
universe.characterizable_base.characteristics.each do |_, c|
|
10
|
+
if c.known?(universe)
|
11
|
+
if c.effective?(universe)
|
12
|
+
self[c.name] = c.value(universe)
|
13
|
+
elsif c.trumped?(universe)
|
14
|
+
trumped_keys.push c.name
|
15
|
+
elsif !c.revealed?(universe)
|
16
|
+
wasted_keys.push c.name
|
17
|
+
lacking_keys.push c.prerequisite
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
def []=(key, value)
|
23
|
+
universe.expire_snapshot!
|
24
|
+
super
|
25
|
+
end
|
26
|
+
def wasted_keys
|
27
|
+
@wasted_keys ||= Array.new
|
28
|
+
end
|
29
|
+
def trumped_keys
|
30
|
+
@trumped_keys ||= Array.new
|
31
|
+
end
|
32
|
+
def lacking_keys
|
33
|
+
@lacking_keys ||= Array.new
|
34
|
+
end
|
35
|
+
def effective
|
36
|
+
universe.characterizable_base.characteristics.select { |_, c| c.effective?(self) }
|
37
|
+
end
|
38
|
+
def potential
|
39
|
+
universe.characterizable_base.characteristics.select { |_, c| c.potential?(self) }
|
40
|
+
end
|
41
|
+
def wasted
|
42
|
+
universe.characterizable_base.characteristics.slice(*wasted_keys)
|
43
|
+
end
|
44
|
+
def lacking
|
45
|
+
universe.characterizable_base.characteristics.slice(*(lacking_keys - wasted_keys))
|
46
|
+
end
|
47
|
+
def trumped
|
48
|
+
universe.characterizable_base.characteristics.slice(*trumped_keys)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class Character
|
4
|
+
include Characterizable
|
5
|
+
end
|
6
|
+
|
7
|
+
class Characterizable::CharacteristicTest < Test::Unit::TestCase
|
8
|
+
context 'display' do
|
9
|
+
setup do
|
10
|
+
@universe = { :charisma => 'hearty' }
|
11
|
+
end
|
12
|
+
|
13
|
+
should 'not display a custom format if display option not given' do
|
14
|
+
char = Characterizable::Characteristic.new(Character, :charisma, {})
|
15
|
+
assert_nil char.display(@universe)
|
16
|
+
end
|
17
|
+
should 'display a custom format if display option is given' do
|
18
|
+
char = Characterizable::Characteristic.new(Character, :charisma,
|
19
|
+
{ :display => lambda { |c| "Level: #{c}" } }) {}
|
20
|
+
assert_equal 'Level: hearty', char.display(@universe)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -39,13 +39,14 @@ end
|
|
39
39
|
|
40
40
|
class SimpleAutomobile
|
41
41
|
include Characterizable
|
42
|
-
attr_accessor :make
|
43
|
-
|
44
|
-
attr_accessor :variant
|
42
|
+
attr_accessor :make, :model, :variant
|
43
|
+
|
45
44
|
characterize do
|
46
45
|
has :make
|
47
|
-
has :model
|
48
|
-
has :variant, :trumps => :model
|
46
|
+
has :model, :display => lambda { |c| "Brand new #{c}" }
|
47
|
+
has :variant, :trumps => :model do
|
48
|
+
displays { |v| "Featuring #{v}" }
|
49
|
+
end
|
49
50
|
end
|
50
51
|
end
|
51
52
|
|
@@ -446,4 +447,12 @@ class TestCharacterizable < Test::Unit::TestCase
|
|
446
447
|
assert_equal [], a.characteristics.lacking.keys
|
447
448
|
assert_equal [], a.characteristics.trumped.keys
|
448
449
|
end
|
450
|
+
|
451
|
+
should 'display custom formats' do
|
452
|
+
sa = SimpleAutomobile.new
|
453
|
+
sa.model = 'FIT'
|
454
|
+
assert_equal 'Brand new FIT', sa.display_characteristic(:model)
|
455
|
+
sa.variant = 'Extreme Edition'
|
456
|
+
assert_equal 'Featuring Extreme Edition', sa.display_characteristic(:variant)
|
457
|
+
end
|
449
458
|
end
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: characterizable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 61
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
7
|
+
- 1
|
8
8
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.17
|
9
|
+
version: 0.1.0
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Andy Rossmeissl
|
@@ -16,7 +15,7 @@ autorequire:
|
|
16
15
|
bindir: bin
|
17
16
|
cert_chain: []
|
18
17
|
|
19
|
-
date: 2010-
|
18
|
+
date: 2010-11-03 00:00:00 -04:00
|
20
19
|
default_executable:
|
21
20
|
dependencies:
|
22
21
|
- !ruby/object:Gem::Dependency
|
@@ -27,7 +26,6 @@ dependencies:
|
|
27
26
|
requirements:
|
28
27
|
- - ">="
|
29
28
|
- !ruby/object:Gem::Version
|
30
|
-
hash: 23
|
31
29
|
segments:
|
32
30
|
- 0
|
33
31
|
- 3
|
@@ -43,7 +41,6 @@ dependencies:
|
|
43
41
|
requirements:
|
44
42
|
- - ">="
|
45
43
|
- !ruby/object:Gem::Version
|
46
|
-
hash: 9
|
47
44
|
segments:
|
48
45
|
- 2
|
49
46
|
- 3
|
@@ -59,7 +56,6 @@ dependencies:
|
|
59
56
|
requirements:
|
60
57
|
- - ">="
|
61
58
|
- !ruby/object:Gem::Version
|
62
|
-
hash: 3
|
63
59
|
segments:
|
64
60
|
- 0
|
65
61
|
version: "0"
|
@@ -83,6 +79,11 @@ files:
|
|
83
79
|
- VERSION
|
84
80
|
- characterizable.gemspec
|
85
81
|
- lib/characterizable.rb
|
82
|
+
- lib/characterizable/base.rb
|
83
|
+
- lib/characterizable/better_hash.rb
|
84
|
+
- lib/characterizable/characteristic.rb
|
85
|
+
- lib/characterizable/snapshot.rb
|
86
|
+
- test/characterizable/test_characteristic.rb
|
86
87
|
- test/helper.rb
|
87
88
|
- test/test_characterizable.rb
|
88
89
|
has_rdoc: true
|
@@ -99,7 +100,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
99
100
|
requirements:
|
100
101
|
- - ">="
|
101
102
|
- !ruby/object:Gem::Version
|
102
|
-
hash: 3
|
103
103
|
segments:
|
104
104
|
- 0
|
105
105
|
version: "0"
|
@@ -108,7 +108,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
108
|
requirements:
|
109
109
|
- - ">="
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
hash: 3
|
112
111
|
segments:
|
113
112
|
- 0
|
114
113
|
version: "0"
|
@@ -120,5 +119,6 @@ signing_key:
|
|
120
119
|
specification_version: 3
|
121
120
|
summary: Characterize instances of a class
|
122
121
|
test_files:
|
122
|
+
- test/characterizable/test_characteristic.rb
|
123
123
|
- test/helper.rb
|
124
124
|
- test/test_characterizable.rb
|