inherited-hash 1.0.0 → 1.0.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.
- data/lib/inherited-hash.rb +36 -23
- data/lib/inherited-hash/version.rb +1 -1
- data/spec/inherited-hash_spec.rb +43 -28
- metadata +4 -4
data/lib/inherited-hash.rb
CHANGED
@@ -1,23 +1,36 @@
|
|
1
1
|
require "inherited-hash/version"
|
2
2
|
|
3
3
|
module InheritedHash
|
4
|
-
def
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
4
|
+
def self.extended(base)
|
5
|
+
base.send(:include, InstanceMethods)
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module InstanceMethods
|
10
|
+
def inherited_hashes
|
11
|
+
@inherited_hashes ||= Hash.new do |h,name|
|
12
|
+
h[name] = ConnectedHash.new.connect(self,name)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
include InstanceMethods
|
19
|
+
|
20
|
+
def inherited_hash_accessor *names
|
21
|
+
names.each do |name|
|
22
|
+
[self,class<<self;self;end].each do |context|
|
23
|
+
context.send(%Q{instance_eval}.to_s) do
|
24
|
+
define_method(name) do
|
25
|
+
inherited_hashes[name]
|
26
|
+
end
|
27
|
+
define_method(%Q{#{name}!}.to_sym) do
|
28
|
+
inherited_hashes[name].to_hash!
|
29
|
+
end
|
30
|
+
define_method(%Q{#{name}=}.to_sym) do |hsh|
|
31
|
+
raise ArgumentError, 'Only hashes are allowed' unless hsh.is_a? Hash
|
32
|
+
inherited_hashes[name].replace(hsh)
|
12
33
|
end
|
13
|
-
instance_variable_get( storage)
|
14
|
-
end
|
15
|
-
define_method(%Q{#{name}!}.to_sym) do
|
16
|
-
send(name).to_hash!
|
17
|
-
end
|
18
|
-
define_method(%Q{#{name}=}.to_sym) do |hsh|
|
19
|
-
raise ArgumentError, 'Only hashes are allowed' unless hsh.is_a? Hash
|
20
|
-
send(name).replace(hsh)
|
21
34
|
end
|
22
35
|
end
|
23
36
|
end
|
@@ -37,11 +50,11 @@ module InheritedHash
|
|
37
50
|
def to_hash!
|
38
51
|
verify!
|
39
52
|
return @anchor.class.send(%Q{#{@name}!}.to_sym).merge(self.to_hash) unless @anchor.is_a? Module
|
40
|
-
|
41
|
-
@anchor.ancestors.reverse.
|
42
|
-
|
43
|
-
|
44
|
-
|
53
|
+
|
54
|
+
@anchor.ancestors.reverse.map do |ancestor|
|
55
|
+
next nil unless ancestor.respond_to?(:inherited_hashes)
|
56
|
+
ancestor.inherited_hashes[@name].to_hash
|
57
|
+
end.compact.reduce({},:merge)
|
45
58
|
end
|
46
59
|
|
47
60
|
def to_hash
|
@@ -53,8 +66,8 @@ module InheritedHash
|
|
53
66
|
return @anchor if has_key? key
|
54
67
|
return @anchor.class.send(@name).find_definition_of(key) unless @anchor.is_a? Module
|
55
68
|
@anchor.ancestors.reverse.index do |ancestor|
|
56
|
-
next
|
57
|
-
return ancestor if ancestor.
|
69
|
+
next nil unless ancestor.respond_to?(:inherited_hashes)
|
70
|
+
return ancestor if ancestor.inherited_hashes[@name].has_key?(key)
|
58
71
|
end
|
59
72
|
end
|
60
73
|
end
|
data/spec/inherited-hash_spec.rb
CHANGED
@@ -40,6 +40,12 @@ describe 'InheritedHash' do
|
|
40
40
|
@s[:leaf2_shoot1] = Class.new(@s[:leaf2]) do
|
41
41
|
foo[:existing_key] = 'changed!'
|
42
42
|
end
|
43
|
+
@s[:leaf_with_colliding_module_extended] = Class.new(@s[:leaf1]) do
|
44
|
+
extend Module.new{ def foo() [] end }
|
45
|
+
end
|
46
|
+
@s[:leaf_with_colliding_module_included] = Class.new(@s[:leaf1]) do
|
47
|
+
include Module.new{ def foo() [] end }
|
48
|
+
end
|
43
49
|
|
44
50
|
@s
|
45
51
|
end
|
@@ -71,36 +77,45 @@ describe 'InheritedHash' do
|
|
71
77
|
subject.foo![:not_overridden].should == "don't override me"
|
72
78
|
end
|
73
79
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
80
|
+
[
|
81
|
+
:leaf1,
|
82
|
+
:leaf_with_colliding_module_extended,
|
83
|
+
:leaf_with_colliding_module_included
|
84
|
+
].compact.each do |node|
|
85
|
+
context "instance of #{node}" do
|
86
|
+
subject do
|
87
|
+
s = @s[node].new
|
88
|
+
s.foo = {:another_new_key => 'ooh, shiny'}
|
89
|
+
s
|
90
|
+
end
|
91
|
+
it 'should have access to instance-set key' do
|
92
|
+
subject.foo![:another_new_key].should == 'ooh, shiny'
|
93
|
+
end
|
94
|
+
it 'should have access to keys inherited from class' do
|
95
|
+
subject.foo![:existing_key].should == 'changed'
|
96
|
+
end
|
97
|
+
it 'should have access to keys inherited from root' do
|
98
|
+
subject.foo![:not_overridden].should == "don't override me"
|
99
|
+
end
|
100
|
+
|
101
|
+
# don't run these on colliding, since colliding by definition breaks this
|
102
|
+
if node == :leaf1
|
103
|
+
it 'should be able to find the definition in the object' do
|
104
|
+
subject.foo.find_definition_of(:another_new_key).should be subject
|
105
|
+
end
|
106
|
+
it 'should be able to find the definition in the class' do
|
107
|
+
subject.foo.find_definition_of(:new_key).should be subject.class
|
108
|
+
subject.foo.find_definition_of(:existing_key).should be subject.class
|
109
|
+
end
|
110
|
+
it 'should be able to find the definition in the root' do
|
111
|
+
subject.foo.find_definition_of(:not_overridden).should be @s[:root]
|
112
|
+
end
|
113
|
+
it 'should not be able to find a definition that does not exist' do
|
114
|
+
subject.foo.find_definition_of(:not_exist).should be_nil
|
115
|
+
end
|
116
|
+
end
|
101
117
|
end
|
102
118
|
end
|
103
119
|
end
|
104
|
-
|
105
120
|
end
|
106
121
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inherited-hash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 1
|
10
|
+
version: 1.0.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ryan Biesemeyer
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2012-01-06 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rspec
|