skn_utils 2.0.6 → 3.0.0
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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/README.md +108 -149
- data/README.rdoc +130 -161
- data/bin/console +8 -0
- data/lib/skn_utils/exploring/configuration.rb +6 -6
- data/lib/skn_utils/nested_result.rb +382 -0
- data/lib/skn_utils/notifier_base.rb +94 -0
- data/lib/skn_utils/version.rb +2 -2
- data/lib/skn_utils.rb +1 -6
- data/skn_utils.gemspec +4 -20
- data/spec/lib/skn_utils/nested_result_spec.rb +268 -0
- data/spec/spec_helper.rb +2 -1
- metadata +27 -36
- data/lib/skn_utils/attribute_helpers.rb +0 -188
- data/lib/skn_utils/generic_bean.rb +0 -20
- data/lib/skn_utils/nested_result_base.rb +0 -123
- data/lib/skn_utils/page_controls.rb +0 -21
- data/lib/skn_utils/result_bean.rb +0 -17
- data/lib/skn_utils/value_bean.rb +0 -20
- data/spec/lib/skn_utils/generic_bean_spec.rb +0 -96
- data/spec/lib/skn_utils/page_controls_spec.rb +0 -124
- data/spec/lib/skn_utils/result_bean_spec.rb +0 -98
- data/spec/lib/skn_utils/value_bean_spec.rb +0 -96
- data/spec/support/shared_example_marshalable_ruby_pojo.rb +0 -54
- data/spec/support/shared_example_ruby_pojo.rb +0 -60
@@ -0,0 +1,268 @@
|
|
1
|
+
##
|
2
|
+
# spec/lib/skn_utils/nested_bean_spec.rb
|
3
|
+
#
|
4
|
+
|
5
|
+
class MyObject
|
6
|
+
|
7
|
+
attr_accessor :some_instance_value
|
8
|
+
|
9
|
+
def initialize(parms)
|
10
|
+
@some_instance_value = parms[:value]
|
11
|
+
end
|
12
|
+
|
13
|
+
def say(str)
|
14
|
+
"saying #{str}!"
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_h
|
18
|
+
hsh = {msg: "You called #{__method__} on me!"}
|
19
|
+
puts hsh
|
20
|
+
hsh
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
RSpec.shared_examples 'plain old ruby object' do
|
26
|
+
|
27
|
+
context "Core Operations " do
|
28
|
+
it 'creates NestedResults all the way down' do
|
29
|
+
expect(object.three.six).to be_a(SknUtils::NestedResult)
|
30
|
+
expect(object.six.last).to be_a(MyObject)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'provides getters' do
|
34
|
+
expect(bean.one).to eql('one')
|
35
|
+
expect(bean[:one]).to eql('one')
|
36
|
+
expect(bean['one']).to eql('one')
|
37
|
+
expect(bean.two).to eql('two')
|
38
|
+
expect(bean[:two]).to eql('two')
|
39
|
+
expect(bean['two']).to eql('two')
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'provides setters' do
|
43
|
+
bean.one = '1'
|
44
|
+
bean.two = '2'
|
45
|
+
expect(bean.two).to eql('2')
|
46
|
+
expect(bean.one).to eql('1')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'can access deeply nested attributes' do
|
50
|
+
expect(bean.six.first.six.eight).to eql('eight')
|
51
|
+
expect(bean.eight.first.first.one).to eql('one')
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'does not affect custom objects being passed in' do
|
55
|
+
expect(bean.four.any_key.some_instance_value).to eql(['MyObject Testing', 'Looking for Modifications'])
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'allows setting of new attributes' do
|
59
|
+
bean.foo = 'bar'
|
60
|
+
expect(bean.foo).to eql('bar')
|
61
|
+
end
|
62
|
+
|
63
|
+
it '#attribute? returns true or false based on true presence and non-blank contents of attribute.' do
|
64
|
+
expect(bean.one?).to be_truthy
|
65
|
+
expect(bean.three.seven?).to be_truthy
|
66
|
+
expect(bean.three.seven).to be false
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'can delete attributes' do
|
70
|
+
bean.delete_field(:two)
|
71
|
+
expect(bean.two?).to be_falsey
|
72
|
+
bean.delete_field(:two)
|
73
|
+
expect(bean.two?).to be_falsey
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'can be accessed just like a hash with indifferent access' do
|
77
|
+
bean.one = '1'
|
78
|
+
expect(bean[:one]).to eql('1')
|
79
|
+
expect(bean['one']).to eql('1')
|
80
|
+
end
|
81
|
+
|
82
|
+
it '#respond_to? replies as expected' do
|
83
|
+
expect(bean.respond_to?(:one)).to be true
|
84
|
+
expect(object2.respond_to?(:eleven)).to be true
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'supports Fixnum keys ' do
|
88
|
+
expect(bean[4201]).to eq 'Account Code'
|
89
|
+
expect(bean[4201] = 'account code').to eq 'account code'
|
90
|
+
expect(bean[4202]).to be_falsey
|
91
|
+
expect(bean[4202] = 'account code').to eq 'account code'
|
92
|
+
end
|
93
|
+
|
94
|
+
it "protected #hash_from returns remaining hash from any root key as the starting point" do
|
95
|
+
expect(bean.send(:hash_from, :one)).to eql({one: 'one'})
|
96
|
+
expect(bean.send(:hash_from, :three)).to eql({three: { four: 4, five: 5, six: { seven: 7, eight: 'eight' }, seven: false }})
|
97
|
+
expect(bean.send(:hash_from, :eight)).to eql({eight: [[{one: 'one', two: 'two'}],[{three: 'three', four: 'four'}]]})
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'Raises NoMethodError in response to invalid key access' do
|
101
|
+
expect{object.sixty_two}.to raise_exception(NoMethodError)
|
102
|
+
end
|
103
|
+
|
104
|
+
context '#attribute? present? like feature operates as expected' do
|
105
|
+
let(:base) do
|
106
|
+
SknUtils::NestedResult.new({
|
107
|
+
empty_string: "", blank_string: " ", null: nil,
|
108
|
+
empty_array: [], blank_arrays: [[]], empty_hash: {}
|
109
|
+
})
|
110
|
+
end
|
111
|
+
|
112
|
+
it '#attribute? returns false when attribute is not defined or unknown' do
|
113
|
+
[:empty_string, :blank_string, :null_string,
|
114
|
+
:empty_hash, :empty_array, :blank_arrays, :twelve].each do |key|
|
115
|
+
expect(base.send(:attribute?, key)).to be false
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
context '#to_h' do
|
123
|
+
let(:hash) { bean.to_h }
|
124
|
+
|
125
|
+
it 'returns a hash of all attributes and their values.' do
|
126
|
+
expect(hash).to be_a(Hash)
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'translates nested objects back to hashes when calling to_h' do
|
130
|
+
expect(hash[:three][:six]).to be_a(Hash)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'translates elements with Fixnum as key back to hashes when calling to_h' do
|
134
|
+
expect(hash[4201]).to eq('Account Code')
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'handles array types when calling to_h' do
|
138
|
+
expect(hash[:six]).to be_a(Array)
|
139
|
+
expect(hash[:six][2]).to be_a(MyObject)
|
140
|
+
expect(hash[:six][0]).to be_a(Hash)
|
141
|
+
expect(hash[:six].size).to eql(3)
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'handles hashes nested in arrays when calling to_h' do
|
145
|
+
expect(hash[:six][0]).to be_a(Hash)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'handles hashes nested in arrays of arrays-of-hashes when calling to_h' do
|
149
|
+
expect(hash[:eight][0][0]).to be_a(Hash)
|
150
|
+
expect(hash[:eight][1][0]).to be_a(Hash)
|
151
|
+
expect(hash[:eight].first.first[:one]).to eql('one')
|
152
|
+
expect(hash[:eight].last.first[:four]).to eql('four')
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'handles non-hash attributes properly' do
|
156
|
+
expect(hash[:one]).to eql('one')
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'does not change custom objects nested in beanure' do
|
160
|
+
expect(hash[:four][:any_key]).to be_a(MyObject)
|
161
|
+
expect(hash[:four][:any_key].some_instance_value).to eql(['MyObject Testing', 'Looking for Modifications'])
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
RSpec.describe SknUtils::NestedResult, 'NestedResult class - Basic usage.' do
|
168
|
+
let(:object) do
|
169
|
+
SknUtils::NestedResult.new(one: 'one', 4201 => 'Account Code',
|
170
|
+
two: 'two',
|
171
|
+
three: { four: 4, five: 5, six: { seven: 7, eight: 'eight' }, seven: false },
|
172
|
+
four: { any_key: MyObject.new(value: ['MyObject Testing', 'Looking for Modifications']) },
|
173
|
+
five: [4, 5, 6],
|
174
|
+
six: [{ four: 4, five: 5, six: { seven: 7, eight: 'eight' } },
|
175
|
+
{ four: 4, five: 5, six: { nine: 9, ten: 'ten' } },
|
176
|
+
MyObject.new(value: ['MyObject Testing', 'Looking for Modifications'])],
|
177
|
+
seven: MyObject.new(value: ['MyObject Testing', 'Looking for Modifications']),
|
178
|
+
eight: [[{one: 'one', two: 'two'}],[{three: 'three', four: 'four'}]])
|
179
|
+
end
|
180
|
+
|
181
|
+
let(:object2) do
|
182
|
+
SknUtils::NestedResult.new({ten: 10,
|
183
|
+
eleven: 11,
|
184
|
+
twelve: [[{five: 5, six: 6}],[{three: 3, '04' => 'four'}]]})
|
185
|
+
end
|
186
|
+
|
187
|
+
let(:json_bean) { object.to_json }
|
188
|
+
|
189
|
+
context 'Initializers' do
|
190
|
+
it 'Creates an empty bean if no params are passed' do
|
191
|
+
is_expected.to be
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'Initializes from a hash' do
|
195
|
+
expect(SknUtils::NestedResult.new(one: 'one', two: 'two')).to be
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'Initializes with attr methods intact after YAML.load' do
|
199
|
+
yamled = Psych.load( Psych.dump(object) )
|
200
|
+
[:one, :two, :three, :four, :five, :six, :seven, :eight].each do |key|
|
201
|
+
expect(yamled.respond_to?(key)).to be true
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
it '#respond_to? verifies attr methods are created on the singleton class and not base class. ' do
|
206
|
+
[:one, :two, :three, :four, :five, :six, :seven, :eight].each do |key|
|
207
|
+
expect(object.respond_to?(key)).to be true
|
208
|
+
end
|
209
|
+
[:one, :two, :three, :four, :five, :six, :seven, :eight].each do |key|
|
210
|
+
expect(object2.respond_to?(key)).to be false
|
211
|
+
end
|
212
|
+
[:ten, :eleven, :twelve].each do |key|
|
213
|
+
expect(object2.respond_to?(key)).to be true
|
214
|
+
end
|
215
|
+
[:ten, :eleven, :twelve].each do |key|
|
216
|
+
expect(object.respond_to?(key)).to be false
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
it '#keys returns array of input hash keys' do
|
221
|
+
expect(object.keys).to eq([:one, 4201, :two, :three, :four, :five, :six, :seven, :eight])
|
222
|
+
end
|
223
|
+
|
224
|
+
end
|
225
|
+
|
226
|
+
context 'Basic Operations without marshaling' do
|
227
|
+
it_behaves_like 'plain old ruby object' do
|
228
|
+
let(:bean) { object }
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context 'Marshalling to JSON' do
|
233
|
+
it 'maintains structure when marshalling to JSON' do
|
234
|
+
expect(JSON.parse(json_bean)['five']).to eql([4, 5, 6])
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
context 'Basic Operations after Yaml marshaling' do
|
239
|
+
let(:dumped_object) { Psych.dump(object) }
|
240
|
+
|
241
|
+
it "#encode_with exports the original hash when YAML'ed" do
|
242
|
+
expect(dumped_object[42..-1]).to_not include('ruby/object:SknUtils::NestedResult')
|
243
|
+
end
|
244
|
+
|
245
|
+
it_behaves_like 'plain old ruby object' do
|
246
|
+
let(:bean) { Psych.load(dumped_object) }
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
context 'NestedResults stripped of their internal singleton accessors can be Marshaled!' do
|
251
|
+
let(:dumped_object) { Psych.dump(object) }
|
252
|
+
let(:loaded_object) { Psych.load(dumped_object) }
|
253
|
+
let(:marshaled_object) { Marshal.dump(loaded_object) }
|
254
|
+
|
255
|
+
it_behaves_like 'plain old ruby object' do
|
256
|
+
let(:bean) { Marshal.load(marshaled_object) }
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
context 'NestedResults Survive direct Marshall' do
|
261
|
+
let(:marshaled_object) { Marshal.dump(object) }
|
262
|
+
|
263
|
+
it_behaves_like 'plain old ruby object' do
|
264
|
+
let(:bean) { Marshal.load(marshaled_object) }
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -6,7 +6,8 @@ require 'skn_utils/exploring/action_service'
|
|
6
6
|
require 'skn_utils/exploring/configuration'
|
7
7
|
|
8
8
|
require 'rspec'
|
9
|
-
require '
|
9
|
+
require 'psych'
|
10
|
+
require 'json'
|
10
11
|
|
11
12
|
# Shared Examples and Support Routines
|
12
13
|
Dir["./spec/support/**/*.rb"].sort.each { |f| require f}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: skn_utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Scott Jr
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,16 +66,23 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: |
|
84
|
+
The intent of NestedResult class is to be a container of data results or key/value pairs, with easy access to its contents, and on-demand transformation back to the hash (#to_hash).
|
85
|
+
Review the RSpec tests, and or review the README for more details.
|
79
86
|
email: skoona@gmail.com
|
80
87
|
executables: []
|
81
88
|
extensions: []
|
@@ -90,30 +97,22 @@ files:
|
|
90
97
|
- README.md
|
91
98
|
- README.rdoc
|
92
99
|
- Rakefile
|
100
|
+
- bin/console
|
93
101
|
- lib/skn_utils.rb
|
94
|
-
- lib/skn_utils/attribute_helpers.rb
|
95
102
|
- lib/skn_utils/exploring/action_service.rb
|
96
103
|
- lib/skn_utils/exploring/commander.rb
|
97
104
|
- lib/skn_utils/exploring/configuration.rb
|
98
|
-
- lib/skn_utils/
|
99
|
-
- lib/skn_utils/
|
105
|
+
- lib/skn_utils/nested_result.rb
|
106
|
+
- lib/skn_utils/notifier_base.rb
|
100
107
|
- lib/skn_utils/null_object.rb
|
101
|
-
- lib/skn_utils/page_controls.rb
|
102
|
-
- lib/skn_utils/result_bean.rb
|
103
|
-
- lib/skn_utils/value_bean.rb
|
104
108
|
- lib/skn_utils/version.rb
|
105
109
|
- skn_utils.gemspec
|
106
110
|
- spec/lib/skn_utils/exploring/action_service_spec.rb
|
107
111
|
- spec/lib/skn_utils/exploring/commander_spec.rb
|
108
112
|
- spec/lib/skn_utils/exploring/configuration_spec.rb
|
109
|
-
- spec/lib/skn_utils/
|
113
|
+
- spec/lib/skn_utils/nested_result_spec.rb
|
110
114
|
- spec/lib/skn_utils/null_object_spec.rb
|
111
|
-
- spec/lib/skn_utils/page_controls_spec.rb
|
112
|
-
- spec/lib/skn_utils/result_bean_spec.rb
|
113
|
-
- spec/lib/skn_utils/value_bean_spec.rb
|
114
115
|
- spec/spec_helper.rb
|
115
|
-
- spec/support/shared_example_marshalable_ruby_pojo.rb
|
116
|
-
- spec/support/shared_example_ruby_pojo.rb
|
117
116
|
homepage: https://github.com/skoona/skn_utils
|
118
117
|
licenses:
|
119
118
|
- MIT
|
@@ -134,23 +133,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
134
133
|
version: '0'
|
135
134
|
requirements: []
|
136
135
|
rubyforge_project:
|
137
|
-
rubygems_version: 2.
|
136
|
+
rubygems_version: 2.6.11
|
138
137
|
signing_key:
|
139
138
|
specification_version: 3
|
140
|
-
summary: Ruby
|
141
|
-
a
|
142
|
-
This class is instantiated via a hash at Ruby Runtime, allowing access to vars
|
143
|
-
via dot or hash notation, and is serializable (<obj>.to_hash) using standard Hash
|
144
|
-
serialization methods.
|
139
|
+
summary: SknUtils contains a small collection of Ruby utilities, the first being a
|
140
|
+
NestedResult a key/value container.
|
145
141
|
test_files:
|
146
142
|
- spec/lib/skn_utils/exploring/action_service_spec.rb
|
147
143
|
- spec/lib/skn_utils/exploring/commander_spec.rb
|
148
144
|
- spec/lib/skn_utils/exploring/configuration_spec.rb
|
149
|
-
- spec/lib/skn_utils/
|
145
|
+
- spec/lib/skn_utils/nested_result_spec.rb
|
150
146
|
- spec/lib/skn_utils/null_object_spec.rb
|
151
|
-
- spec/lib/skn_utils/page_controls_spec.rb
|
152
|
-
- spec/lib/skn_utils/result_bean_spec.rb
|
153
|
-
- spec/lib/skn_utils/value_bean_spec.rb
|
154
147
|
- spec/spec_helper.rb
|
155
|
-
- spec/support/shared_example_marshalable_ruby_pojo.rb
|
156
|
-
- spec/support/shared_example_ruby_pojo.rb
|
@@ -1,188 +0,0 @@
|
|
1
|
-
##
|
2
|
-
# <project.root>/lib/skn_utils/attribute_helpers.rb
|
3
|
-
#
|
4
|
-
# *** See SknUtils::NestedResultBase for details ***
|
5
|
-
#
|
6
|
-
##
|
7
|
-
# This module provides
|
8
|
-
#
|
9
|
-
# to_hash Serializer:
|
10
|
-
# person.to_hash
|
11
|
-
# => {"name"=>"Bob"}
|
12
|
-
#
|
13
|
-
# Support <attr>? and clear_<attr>? method patterns
|
14
|
-
# example:
|
15
|
-
# person.name?
|
16
|
-
# => true true or false, like obj.name.present?
|
17
|
-
# person.clear_name
|
18
|
-
# => nil sets :name to nil
|
19
|
-
#
|
20
|
-
# attr_accessor like feature for all instance variables
|
21
|
-
# person.name
|
22
|
-
# => "Bob"
|
23
|
-
# person.name = "James"
|
24
|
-
# => "James"
|
25
|
-
##
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
module SknUtils
|
30
|
-
module AttributeHelpers
|
31
|
-
|
32
|
-
# These methods normally come from ActiveSupport in Rails
|
33
|
-
# If your not using this gem with Rails, then the :included method
|
34
|
-
# will add these routines to the Object class
|
35
|
-
def self.included(mod)
|
36
|
-
unless Object.respond_to? :instance_variable_names
|
37
|
-
Object.class_exec {
|
38
|
-
def instance_variable_names
|
39
|
-
instance_variables.map { |var| var.to_s }
|
40
|
-
end
|
41
|
-
def instance_values
|
42
|
-
Hash[instance_variables.map { |name| [name[1..-1], instance_variable_get(name)] }]
|
43
|
-
end
|
44
|
-
}
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
# return a hash of all attributes and their current values
|
49
|
-
# including nested arrays of hashes/objects
|
50
|
-
def attributes(filter_internal=true)
|
51
|
-
instance_variable_names.each_with_object({}) do |attr,collector|
|
52
|
-
next if ['skn_enable_serialization', 'skn_enabled_depth'].include?(attr.to_s[1..-1]) and filter_internal # skip control keys
|
53
|
-
value = instance_variable_get(attr)
|
54
|
-
|
55
|
-
if value.kind_of?(Array) and value.first.respond_to?(:attribute_helper_object)
|
56
|
-
value = value.map {|ov| ov.respond_to?(:attribute_helper_object) ? ov.attributes : ov }
|
57
|
-
elsif value.respond_to?(:attribute_helper_object)
|
58
|
-
value = value.attributes
|
59
|
-
end
|
60
|
-
collector[attr.to_s[1..-1].to_sym] = value
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def to_hash(exclude_internal_vars=false)
|
65
|
-
attributes(!exclude_internal_vars)
|
66
|
-
end
|
67
|
-
alias_method :to_h, :to_hash
|
68
|
-
|
69
|
-
# An alternative mechanism for property access.
|
70
|
-
# Hash notation
|
71
|
-
def [](attr)
|
72
|
-
send("#{attr}")
|
73
|
-
end
|
74
|
-
|
75
|
-
# Hash notation
|
76
|
-
def []=(attr, value)
|
77
|
-
send("#{attr}=", value)
|
78
|
-
end
|
79
|
-
|
80
|
-
##
|
81
|
-
# DO NOT ADD METHODS BELOW THIS LINE, unless you want them to be private
|
82
|
-
##
|
83
|
-
|
84
|
-
# Support the regular respond_to? method by
|
85
|
-
# answering for any attr that method missing actually handle
|
86
|
-
#:nodoc:
|
87
|
-
def respond_to_missing?(method, incl_private=false)
|
88
|
-
instance_variable_names.include?("@#{method.to_s}") || super(method,incl_private)
|
89
|
-
end
|
90
|
-
|
91
|
-
private
|
92
|
-
|
93
|
-
# Deals with the true existance of an attribute and then its non-blank or empty value
|
94
|
-
# - attribute must exist and have a non-blank value to cause this method to return true
|
95
|
-
#:nodoc:
|
96
|
-
def attribute?(attr)
|
97
|
-
return false unless instance_variable_names.include?("@#{attr.to_s}")
|
98
|
-
if attr.is_a? Symbol
|
99
|
-
![ "", " ", nil, [],[""], [" "], {} ].include?( send(attr) )
|
100
|
-
else
|
101
|
-
![ "", " ", nil, [],[""], [" "], {} ].include?( send(attr.to_sym) )
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
#:nodoc:
|
106
|
-
def clear_attribute(attr)
|
107
|
-
if attr.is_a? Symbol
|
108
|
-
instance_variable_set("@#{attr.to_s}", nil)
|
109
|
-
else
|
110
|
-
instance_variable_set("@#{attr}", nil)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
# Determines operable Options in effect for this instance
|
115
|
-
# see NestedResultBase
|
116
|
-
#:nodoc:
|
117
|
-
def serial_required?
|
118
|
-
respond_to? :serialization_required? and serialization_required?
|
119
|
-
end
|
120
|
-
# see NestedResultBase
|
121
|
-
#:nodoc:
|
122
|
-
def multi_required?
|
123
|
-
respond_to? :depth_level and depth_level != :single
|
124
|
-
end
|
125
|
-
# see NestedResultBase
|
126
|
-
#:nodoc:
|
127
|
-
def multi_with_arrays_required?
|
128
|
-
respond_to? :depth_level and depth_level == :multi_with_arrays
|
129
|
-
end
|
130
|
-
|
131
|
-
##
|
132
|
-
# Adds the attr?() method pattern. all attributes will respond to attr?: example - obj.name? with true or false
|
133
|
-
# Adds the clear_attr() method pattern. all attributes will respond to clear_attr(): example - obj.clear_name sets :name to nil
|
134
|
-
# Handles getter for any instance_variable currently defined
|
135
|
-
# Handles setter for any instance_variable currently defined
|
136
|
-
# Sets new instance_variable for any undefined variable with non-hash value
|
137
|
-
# Sets instance_variable value to Bean object for any undefined variable with hash value param
|
138
|
-
#
|
139
|
-
# Using any form of singleton_class() will break the generic bean, which requires Serialization.
|
140
|
-
# However not adding attr_accessors may impact performance, as method_missing must fill-in for read/writes
|
141
|
-
##
|
142
|
-
#:nodoc:
|
143
|
-
def method_missing(method, *args, &block)
|
144
|
-
# puts("method_missing/method/class/*args=#{method}/#{method.class.name}/#{args}")
|
145
|
-
if method.to_s.start_with?('clear_') and instance_variable_defined?("@#{method.to_s[6..-1]}")
|
146
|
-
clear_attribute(method.to_s[6..-1].to_sym)
|
147
|
-
elsif method.to_s.end_with?('?')
|
148
|
-
if instance_variable_defined?("@#{method.to_s[0..-2]}")
|
149
|
-
attribute?(method.to_s[0..-2].to_sym)
|
150
|
-
else
|
151
|
-
false
|
152
|
-
end
|
153
|
-
elsif method.to_s.end_with?("=") # add new attribute or whole object
|
154
|
-
if args.first.is_a?(Hash)
|
155
|
-
singleton_class.send(:attr_accessor, method.to_s[0..-2]) unless serial_required?
|
156
|
-
if multi_required?
|
157
|
-
instance_variable_set "@#{method.to_s[0..-2]}", self.class.new(*args)
|
158
|
-
else
|
159
|
-
instance_variable_set "@#{method.to_s[0..-2]}", *args
|
160
|
-
end
|
161
|
-
elsif args.first.is_a?(Array) and args.flatten.first.kind_of?(Hash)
|
162
|
-
singleton_class.send(:attr_accessor, method.to_s[0..-2]) unless serial_required?
|
163
|
-
if multi_with_arrays_required?
|
164
|
-
instance_variable_set("@#{method.to_s[0..-2]}",
|
165
|
-
(args.first.map {|nobj| nobj.kind_of?(Hash) ? self.class.new(nobj) : nobj })
|
166
|
-
)
|
167
|
-
else
|
168
|
-
instance_variable_set "@#{method.to_s[0..-2]}", *args
|
169
|
-
end
|
170
|
-
elsif !args.empty?
|
171
|
-
singleton_class.send(:attr_accessor, method.to_s[0..-2]) unless serial_required?
|
172
|
-
instance_variable_set "@#{method.to_s[0..-2]}", *args
|
173
|
-
else
|
174
|
-
super(method, *args, &block) # throw excpt for not found or could return false
|
175
|
-
end
|
176
|
-
elsif instance_variable_defined? "@#{method.to_s}"
|
177
|
-
instance_variable_get "@#{method.to_s}"
|
178
|
-
else
|
179
|
-
super(method, *args, &block)
|
180
|
-
end
|
181
|
-
rescue
|
182
|
-
# puts $!.message + $!.backtrace.join("\n")
|
183
|
-
super(method, *args, &block)
|
184
|
-
end
|
185
|
-
# end of private section
|
186
|
-
|
187
|
-
end # end module
|
188
|
-
end # end module
|
@@ -1,20 +0,0 @@
|
|
1
|
-
##
|
2
|
-
# <project.root>/lib/skn_utils/generic_bean.rb
|
3
|
-
#
|
4
|
-
# *** See SknUtils::NestedResultBase for details ***
|
5
|
-
#
|
6
|
-
##
|
7
|
-
# (Defaults)
|
8
|
-
# :enable_serialization = true
|
9
|
-
# :depth = :multi
|
10
|
-
|
11
|
-
module SknUtils
|
12
|
-
|
13
|
-
class GenericBean < NestedResultBase
|
14
|
-
#:nodoc:
|
15
|
-
def initialize(params={})
|
16
|
-
super( params.merge({enable_serialization: true}) )
|
17
|
-
end
|
18
|
-
end # end class
|
19
|
-
|
20
|
-
end # end module
|