inherited-hash 1.0.0 → 1.0.1

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