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.
@@ -1,23 +1,36 @@
1
1
  require "inherited-hash/version"
2
2
 
3
3
  module InheritedHash
4
- def inherited_hash_accessor *names
5
- names.each do |name|
6
- [self,class<<self;self;end].each do |context|
7
- context.send(%Q{instance_eval}.to_s) do
8
- define_method(name) do
9
- storage = %Q{@#{name}}.to_sym
10
- unless instance_variable_defined?( storage )
11
- instance_variable_set(storage, InheritedHash::ConnectedHash.new.connect(self,name))
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
- hash = Hash.new
41
- @anchor.ancestors.reverse.each do |ancestor|
42
- hash.merge!(ancestor.send(@name).to_hash) if ancestor.respond_to?(@name)
43
- end
44
- hash
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 false unless ancestor.respond_to?(@name)
57
- return ancestor if ancestor.send(@name).has_key?(key)
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
@@ -1,3 +1,3 @@
1
1
  module InheritedHash
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -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
- context 'instance' do
75
- subject do
76
- s = @s[:leaf1].new
77
- s.foo = {:another_new_key => 'ooh, shiny'}
78
- s
79
- end
80
- it 'should have access to instance-set key' do
81
- subject.foo![:another_new_key].should == 'ooh, shiny'
82
- end
83
- it 'should have access to keys inherited from class' do
84
- subject.foo![:existing_key].should == 'changed'
85
- end
86
- it 'should have access to keys inherited from root' do
87
- subject.foo![:not_overridden].should == "don't override me"
88
- end
89
- it 'should be able to find the definition in the object' do
90
- subject.foo.find_definition_of(:another_new_key).should be subject
91
- end
92
- it 'should be able to find the definition in the class' do
93
- subject.foo.find_definition_of(:new_key).should be subject.class
94
- subject.foo.find_definition_of(:existing_key).should be subject.class
95
- end
96
- it 'should be able to find the definition in the root' do
97
- subject.foo.find_definition_of(:not_overridden).should be @s[:root]
98
- end
99
- it 'should not be able to find a definition that does not exist' do
100
- subject.foo.find_definition_of(:not_exist).should be_nil
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: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 0
10
- version: 1.0.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: 2011-11-02 00:00:00 Z
18
+ date: 2012-01-06 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rspec