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,382 @@
|
|
1
|
+
##
|
2
|
+
# <project.root>/lib/skn_utils/nested_result.rb
|
3
|
+
#
|
4
|
+
# SknUtils::NestedResult Value Container/Class for Ruby with Indifferent Hash and/or Dot.notation access
|
5
|
+
#
|
6
|
+
# Description:
|
7
|
+
#
|
8
|
+
# Creates an Object with attribute methods for dot.notation and hash.notation access
|
9
|
+
# for each hash input key/value pair.
|
10
|
+
#
|
11
|
+
# If the key's value is an hash itself, it will become an NestedResult Object.
|
12
|
+
# if the key's value is an Array of Hashes, each hash element of the Array will
|
13
|
+
# become an Object; non-hash object are left as-is
|
14
|
+
# if the key's value is an Array of Arrays-of- Hash/Object, each hash element of each Array will
|
15
|
+
# become an Object; non-hash object are left as-is. This array of array of arrays
|
16
|
+
# goes on to the end.
|
17
|
+
#
|
18
|
+
# Transforms entire input hash contents into dot.notation and hash.notation accessible key/value pairs.
|
19
|
+
# - hash
|
20
|
+
# - array of hashes
|
21
|
+
# - non hash element values are not modified,
|
22
|
+
# whether in an array or the basic value in a key/value pair
|
23
|
+
#
|
24
|
+
# The ability of the resulting Object to be YAML/Psych'ed, or Marshaled(dump/load) is preserved
|
25
|
+
#
|
26
|
+
##
|
27
|
+
# Transforms entire input hash contents into dot.notation accessible object
|
28
|
+
# - hash
|
29
|
+
# - array of hashes
|
30
|
+
# - non hash element values are not modified, whether in an array or the basic value in a key/value pair
|
31
|
+
#
|
32
|
+
##
|
33
|
+
# This module provides
|
34
|
+
#
|
35
|
+
# Simple Initialization Pattern
|
36
|
+
# person = SknUtils::NestedResult.new( {name: "Bob", title: {day: 'Analyst', night: 'Fireman'}} )
|
37
|
+
#
|
38
|
+
# Serializers:
|
39
|
+
# person.to_hash
|
40
|
+
# => {name: 'Bob', title: {day: 'Analyst', night: 'Fireman'}}
|
41
|
+
# person.to_json
|
42
|
+
# => "{\"name\":\"Bob\", \"title\":{\"day\":\"Analyst\", \"night\":\"Fireman\"}}"
|
43
|
+
#
|
44
|
+
# Dynamic addition of new key/values after initialization
|
45
|
+
# person.address = 'Fort Wayne Indiana'
|
46
|
+
# person.address
|
47
|
+
# => 'Fort Wayne Indiana'
|
48
|
+
#
|
49
|
+
# dot.notation feature for all instance variables
|
50
|
+
# person.title.day
|
51
|
+
# => "Analyst"
|
52
|
+
# person.name = "James"
|
53
|
+
# => "James"
|
54
|
+
#
|
55
|
+
# InDifferent String/Symbol hash[notation] feature for all instance variables
|
56
|
+
# person['title']['day']
|
57
|
+
# => "Analyst"
|
58
|
+
# person['name'] = "James"
|
59
|
+
# => "James"
|
60
|
+
# person[:name]
|
61
|
+
# => "James"
|
62
|
+
# person[:name] = "Bob"
|
63
|
+
# => "Bob"
|
64
|
+
#
|
65
|
+
# Supports <attr>? predicate method patterns, and delete_field(:attr) method
|
66
|
+
# example:
|
67
|
+
# person.title.night?
|
68
|
+
# => true true or false, like obj.name.present?
|
69
|
+
# person.delete_field(:name) only first/root level attributes can be deleted
|
70
|
+
# => 'Bob' returns last value of deleted key
|
71
|
+
# person.name_not_found
|
72
|
+
# => NoMethodFound raises exception if key is not found
|
73
|
+
#
|
74
|
+
# Exporting hash from any key starting point
|
75
|
+
# person.hash_from(:name)
|
76
|
+
# => {name: 'Bob'} the entire hash tree from that starting point
|
77
|
+
##
|
78
|
+
# Advanced Methods
|
79
|
+
# #to_hash - returns copy of input hash
|
80
|
+
# #to_json(*args) - converts input hash into JSON
|
81
|
+
# #keys - returns the first-level keys of input hash
|
82
|
+
# #delete_field(attr_sym) - removes attribute/key and returns it's former value
|
83
|
+
# #hash_from(starting_attr_sym) - (Protected Method) returns remaining hash starting from key provided
|
84
|
+
#
|
85
|
+
##
|
86
|
+
# Known Issues
|
87
|
+
# - Fixnum keys work as keys with the exception of #respond_to?() which does not support them
|
88
|
+
# - Entries with Fixnums or object-instance keys are accessible only via #[]=(), #[] Hash.notation
|
89
|
+
# methods and not the dot.notation feature
|
90
|
+
#
|
91
|
+
###################################################################################################
|
92
|
+
|
93
|
+
module SknUtils
|
94
|
+
class NestedResult
|
95
|
+
|
96
|
+
def initialize(params={})
|
97
|
+
@container = {}
|
98
|
+
initialize_from_hash(params)
|
99
|
+
end
|
100
|
+
|
101
|
+
def [](attr)
|
102
|
+
container[key_as_sym(attr)]
|
103
|
+
end
|
104
|
+
|
105
|
+
#Feature: if a new attribute is added, on first read method_missing will create getters/setters
|
106
|
+
def []=(attr, value)
|
107
|
+
container.store(key_as_sym(attr), value)
|
108
|
+
end
|
109
|
+
|
110
|
+
def delete_field(name) # protect public methods
|
111
|
+
sym = key_as_sym(name)
|
112
|
+
unless !sym.is_a?(Symbol) || self.class.method_defined?(sym)
|
113
|
+
singleton_class.send(:remove_method, "#{sym.to_s}=".to_sym, sym) rescue nil
|
114
|
+
container.delete(sym)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
#
|
119
|
+
# Exporters
|
120
|
+
#
|
121
|
+
def to_hash
|
122
|
+
attributes
|
123
|
+
end
|
124
|
+
|
125
|
+
alias_method :to_h, :to_hash
|
126
|
+
|
127
|
+
def to_json(*args)
|
128
|
+
attributes.to_json(*args)
|
129
|
+
end
|
130
|
+
|
131
|
+
#
|
132
|
+
# Returns a string containing a detailed summary of the keys and values.
|
133
|
+
#
|
134
|
+
InspectKey = :__inspect_key__ # :nodoc:
|
135
|
+
def inspect
|
136
|
+
package = to_hash
|
137
|
+
str = "#<#{self.class}"
|
138
|
+
|
139
|
+
ids = (Thread.current[InspectKey] ||= [])
|
140
|
+
if ids.include?(object_id)
|
141
|
+
return str << ' ...>'
|
142
|
+
end
|
143
|
+
|
144
|
+
ids << object_id
|
145
|
+
begin
|
146
|
+
first = true
|
147
|
+
for k,v in package
|
148
|
+
str << "," unless first
|
149
|
+
first = false
|
150
|
+
str << " #{k}=#{v.inspect}"
|
151
|
+
end
|
152
|
+
return str << '>'
|
153
|
+
ensure
|
154
|
+
ids.pop
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
alias_method :to_s, :inspect
|
159
|
+
|
160
|
+
|
161
|
+
##
|
162
|
+
# Ruby basic Class methods
|
163
|
+
#
|
164
|
+
def ==(other)
|
165
|
+
return false unless other.is_a?(NestedResult)
|
166
|
+
to_hash.eql?(other.to_hash)
|
167
|
+
end
|
168
|
+
alias_method :===, :==
|
169
|
+
|
170
|
+
def eql?(other)
|
171
|
+
return false unless other.is_a?(NestedResult)
|
172
|
+
to_hash.eql?(other.to_hash)
|
173
|
+
end
|
174
|
+
|
175
|
+
def hash
|
176
|
+
to_hash.hash
|
177
|
+
end
|
178
|
+
|
179
|
+
# Feature: returns keys from root input Hash
|
180
|
+
def keys
|
181
|
+
container.keys
|
182
|
+
end
|
183
|
+
|
184
|
+
##
|
185
|
+
# YAML/Psych load support, chance to re-initialize value methods
|
186
|
+
#
|
187
|
+
# Use our unwrapped/original input Hash when yaml'ing
|
188
|
+
def encode_with(coder)
|
189
|
+
coder['container'] = self.to_h
|
190
|
+
end
|
191
|
+
|
192
|
+
# Use our hash from above to fully re-initialize this instance
|
193
|
+
def init_with(coder)
|
194
|
+
case coder.tag
|
195
|
+
when '!ruby/object:SknUtils::NestedResult'
|
196
|
+
initialize_from_hash( coder.map['container'] )
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
protected
|
201
|
+
|
202
|
+
##
|
203
|
+
# Marshal.load()/.dump() support, chance to re-initialize value methods
|
204
|
+
#
|
205
|
+
def marshal_dump
|
206
|
+
to_hash
|
207
|
+
end
|
208
|
+
|
209
|
+
# Using the String from above create and return an instance of this class
|
210
|
+
def marshal_load(hash)
|
211
|
+
initialize_from_hash(hash)
|
212
|
+
end
|
213
|
+
|
214
|
+
def respond_to_missing?(method, incl_private=false)
|
215
|
+
method_nsym = method.is_a?(Symbol) ? method.to_s[0..-2].to_sym : method
|
216
|
+
container[key_as_sym(method)] || container[method_nsym] || super
|
217
|
+
end
|
218
|
+
|
219
|
+
private
|
220
|
+
|
221
|
+
# Feature: attribute must exist and have a non-blank value to cause this method to return true
|
222
|
+
def attribute?(attr)
|
223
|
+
return false unless container.key?(key_as_sym(attr))
|
224
|
+
![ "", " ", nil, [],[""], [" "], NestedResult.new({}), [[]]].any? {|a| a == container[key_as_sym(attr)] }
|
225
|
+
end
|
226
|
+
|
227
|
+
# Feature: returns a hash of all attributes and their current values
|
228
|
+
def attributes
|
229
|
+
hash_from(container)
|
230
|
+
end
|
231
|
+
|
232
|
+
def container
|
233
|
+
@container ||= {}
|
234
|
+
end
|
235
|
+
|
236
|
+
# returns hash from any root key starting point: object.root_key
|
237
|
+
# - protected to reasonably ensure key is a symbol
|
238
|
+
def hash_from(sym)
|
239
|
+
starting_sym = key_as_sym(sym)
|
240
|
+
bundle = starting_sym == container ? container : { starting_sym => container[starting_sym] }
|
241
|
+
bundle.keys.each_with_object({}) do |attr,collector|
|
242
|
+
value = bundle[attr]
|
243
|
+
case value
|
244
|
+
when Array
|
245
|
+
value = value.map {|ele| array_to_hash(ele) }
|
246
|
+
when NestedResult
|
247
|
+
value = value.to_hash
|
248
|
+
end
|
249
|
+
collector[attr] = value # new copy
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
# Feature: enables dot.notation and creates matching getter/setters
|
254
|
+
def enable_dot_notation(sym)
|
255
|
+
name = key_as_sym(sym)
|
256
|
+
unless !name.is_a?(Symbol) || singleton_class.method_defined?(name)
|
257
|
+
singleton_class.send(:define_method, name) do
|
258
|
+
container[name]
|
259
|
+
end
|
260
|
+
|
261
|
+
singleton_class.send(:define_method, "#{name.to_s}=".to_sym) do |x|
|
262
|
+
container[name] = x
|
263
|
+
end
|
264
|
+
end
|
265
|
+
name
|
266
|
+
end
|
267
|
+
|
268
|
+
def initialize_from_hash(hash)
|
269
|
+
hash.each_pair do |k,v|
|
270
|
+
key = key_as_sym(k)
|
271
|
+
enable_dot_notation(key)
|
272
|
+
case v
|
273
|
+
when Array
|
274
|
+
value = v.map { |element| translate_value(element) }
|
275
|
+
container.store(key, value)
|
276
|
+
when Hash
|
277
|
+
container.store(key, NestedResult.new(v))
|
278
|
+
else
|
279
|
+
container.store(key, v)
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
# Feature: unwrap array of array-of-hashes/object
|
285
|
+
def array_to_hash(array)
|
286
|
+
case array
|
287
|
+
when Array
|
288
|
+
array.map { |element| array_to_hash(element) }
|
289
|
+
when NestedResult
|
290
|
+
array.to_hash
|
291
|
+
else
|
292
|
+
array
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
# Feature: wrap array of array-of-hashes/object
|
297
|
+
def translate_value(value)
|
298
|
+
case value
|
299
|
+
when Array
|
300
|
+
value.map { |element| translate_value(element) }
|
301
|
+
when Hash
|
302
|
+
NestedResult.new(value)
|
303
|
+
else
|
304
|
+
value
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
def key_as_sym(key)
|
309
|
+
case key
|
310
|
+
when Symbol
|
311
|
+
key
|
312
|
+
when String
|
313
|
+
key.to_sym
|
314
|
+
else
|
315
|
+
key # no change, allows Fixnum and Object instances
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
# Feature: post-assign key/value pair, <attr>?? predicate, create getter/setter on first access
|
320
|
+
def method_missing(method, *args, &block)
|
321
|
+
method_sym = key_as_sym(method)
|
322
|
+
method_nsym = method_sym.is_a?(Symbol) ? method.to_s[0..-2].to_sym : method
|
323
|
+
|
324
|
+
|
325
|
+
if method.to_s.end_with?("=") and container[method_nsym].nil? # add new key/value pair, transform value if Hash or Array
|
326
|
+
initialize_from_hash({method_nsym => args.first})
|
327
|
+
|
328
|
+
elsif container.key?(method_sym)
|
329
|
+
puts "#{__method__}() method: #{method}"
|
330
|
+
enable_dot_notation(method_sym) # Add Reader/Writer one first need
|
331
|
+
container[method_sym]
|
332
|
+
|
333
|
+
elsif method.to_s.end_with?('?') # order of tests is significant,
|
334
|
+
attribute?(method_nsym)
|
335
|
+
|
336
|
+
else
|
337
|
+
e = NoMethodError.new "undefined method `#{method}' for #{self.class.name}", method, args
|
338
|
+
e.set_backtrace caller(1)
|
339
|
+
raise e
|
340
|
+
|
341
|
+
end
|
342
|
+
end # end method_missing: errors from enable_dot..., initialize_hash..., and attribute? are possible
|
343
|
+
|
344
|
+
end # end class
|
345
|
+
end # end module
|
346
|
+
|
347
|
+
|
348
|
+
# YAML.load(str) will trigger #init_with for each type it encounters when loading
|
349
|
+
# Psych.dump ==> "--- !ruby/object:SknUtils::NestedResult\ncontainer:\n :one: 1\n :two: two\n"
|
350
|
+
#
|
351
|
+
#
|
352
|
+
# [2] pry(main)> ay = Psych.dump a
|
353
|
+
# respond_to_missing?() checking for method: :encode_with existence.
|
354
|
+
# => "--- !ruby/object:SknUtils::NestedResult\ncontainer:\n :one: 1\n :two: two\n"
|
355
|
+
# [3] pry(main)> az = Psych.load ay
|
356
|
+
# respond_to_missing?() checking for method: :init_with existence.
|
357
|
+
# respond_to_missing?() checking for method: :yaml_initialize existence.
|
358
|
+
# => #<SknUtils::NestedResult:0x007fe410993238 @container={:one=>1, :two=>"two"}>
|
359
|
+
|
360
|
+
|
361
|
+
# YAML RTM? querys
|
362
|
+
# [:encode_with, :init_with].include?(method)
|
363
|
+
|
364
|
+
|
365
|
+
# can be accessed just like a hash
|
366
|
+
# respond_to_missing?() checking for method: :encode_with existence.
|
367
|
+
# respond_to_missing?() checking for method: :encode_with existence.
|
368
|
+
# respond_to_missing?() checking for method: :encode_with existence.
|
369
|
+
# respond_to_missing?() checking for method: :encode_with existence.
|
370
|
+
# respond_to_missing?() checking for method: :encode_with existence.
|
371
|
+
# respond_to_missing?() checking for method: :encode_with existence.
|
372
|
+
# respond_to_missing?() checking for method: :encode_with existence.
|
373
|
+
# respond_to_missing?() checking for method: :encode_with existence.
|
374
|
+
# init_with() hooking into Yaml/Psych.load for codes: {:seven=>7, :eight=>"eight"}.
|
375
|
+
# init_with() hooking into Yaml/Psych.load for codes: {:four=>4, :five=>5, :six=>#<SknUtils::NestedResult:0x007fba101740e0 @container={:seven=>7, :eight=>"eight"}>, :seven=>false}.
|
376
|
+
# init_with() hooking into Yaml/Psych.load for codes: {:any_key=>#<Tuple:0x007fba101643e8 @first="foo", @second="bar">}.
|
377
|
+
# init_with() hooking into Yaml/Psych.load for codes: {:seven=>7, :eight=>"eight"}.
|
378
|
+
# init_with() hooking into Yaml/Psych.load for codes: {:four=>4, :five=>5, :six=>#<SknUtils::NestedResult:0x007fba1014f880 @container={:seven=>7, :eight=>"eight"}>}.
|
379
|
+
# init_with() hooking into Yaml/Psych.load for codes: {:nine=>9, :ten=>"ten"}.
|
380
|
+
# init_with() hooking into Yaml/Psych.load for codes: {:four=>4, :five=>5, :six=>#<SknUtils::NestedResult:0x007fba1014cd60 @container={:nine=>9, :ten=>"ten"}>}.
|
381
|
+
# init_with() hooking into Yaml/Psych.load for codes: {:one=>"one", :two=>"two", :three=>#<SknUtils::NestedResult:0x007fba10175058 @container={:four=>4, :five=>5, :six=>#<SknUtils::NestedResult:0x007fba101740e0 @container={:seven=>7, :eight=>"eight"}>, :seven=>false}>, :four=>#<SknUtils::NestedResult:0x007fba101664b8 @container={:any_key=>#<Tuple:0x007fba101643e8 @first="foo", @second="bar">}>, :five=>[4, 5, 6], :six=>[#<SknUtils::NestedResult:0x007fba10154628 @container={:four=>4, :five=>5, :six=>#<SknUtils::NestedResult:0x007fba1014f880 @container={:seven=>7, :eight=>"eight"}>}>, #<SknUtils::NestedResult:0x007fba1014d738 @container={:four=>4, :five=>5, :six=>#<SknUtils::NestedResult:0x007fba1014cd60 @container={:nine=>9, :ten=>"ten"}>}>, #<Tuple:0x007fba10146d48 @first="another", @second="tuple">], :seven=>#<Tuple:0x007fba10145a60 @first="hello", @second="world">}.
|
382
|
+
|
@@ -0,0 +1,94 @@
|
|
1
|
+
#
|
2
|
+
#
|
3
|
+
# Ruby Notify like class
|
4
|
+
#
|
5
|
+
# Ref: https://ozone.wordpress.com/category/programming/metaprogramming/
|
6
|
+
|
7
|
+
|
8
|
+
class NotifierBase
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@listeners = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def register_listener(l)
|
15
|
+
@listeners.push(l) unless @listeners.include?(l)
|
16
|
+
end
|
17
|
+
|
18
|
+
def unregister_listener(l)
|
19
|
+
@listeners.delete(l)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.attribute(*properties)
|
23
|
+
properties.each do |prop|
|
24
|
+
define_method(prop) {
|
25
|
+
instance_variable_get("@#{prop}")
|
26
|
+
}
|
27
|
+
define_method("#{prop}=") do |value|
|
28
|
+
old_value = instance_variable_get("@#{prop}")
|
29
|
+
return if (value == old_value)
|
30
|
+
@listeners.each { |listener|
|
31
|
+
listener.attribute_changed(prop, old_value, value)
|
32
|
+
}
|
33
|
+
instance_variable_set("@#{prop}", value)
|
34
|
+
end
|
35
|
+
end # loop on properties
|
36
|
+
end # end of attribute method
|
37
|
+
|
38
|
+
end # end of NotifierBase class
|
39
|
+
|
40
|
+
|
41
|
+
# Create a bean from that base
|
42
|
+
class TestBean < NotifierBase
|
43
|
+
attribute :name, :firstname
|
44
|
+
end
|
45
|
+
|
46
|
+
class LoggingPropertyChangeListener
|
47
|
+
def attribute_changed(attribute, old_value, new_value)
|
48
|
+
print attribute, " changed from ",
|
49
|
+
old_value, " to ",
|
50
|
+
new_value, "\n"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class SimpleBean < NotifierBase
|
55
|
+
attribute :name, :firstname
|
56
|
+
|
57
|
+
def impotent_name=(new_name)
|
58
|
+
@name = new_name
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
test = TestBean.new
|
64
|
+
listener = LoggingPropertyChangeListener.new
|
65
|
+
test.register_listener(listener)
|
66
|
+
test.name = 'James Scott'
|
67
|
+
test.firstname = "Scott"
|
68
|
+
test.firstname = "James"
|
69
|
+
test.unregister_listener(listener)
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
test = SimpleBean.new
|
74
|
+
listener = LoggingPropertyChangeListener.new
|
75
|
+
test.register_listener(listener)
|
76
|
+
test.name = 'James Scott'
|
77
|
+
test.firstname = 'Scott'
|
78
|
+
test.firstname = 'James'
|
79
|
+
test.unregister_listener(listener)
|
80
|
+
|
81
|
+
|
82
|
+
# output it generates:
|
83
|
+
|
84
|
+
# ==> name changed from nil to James Scott
|
85
|
+
# ==> firstname changed from nil to Scott
|
86
|
+
# ==> firstname changed from Scott to James
|
87
|
+
|
88
|
+
|
89
|
+
#
|
90
|
+
# END
|
91
|
+
#
|
92
|
+
|
93
|
+
|
94
|
+
|
data/lib/skn_utils/version.rb
CHANGED
data/lib/skn_utils.rb
CHANGED
@@ -1,10 +1,5 @@
|
|
1
1
|
require "skn_utils/version"
|
2
|
-
require 'skn_utils/
|
3
|
-
require 'skn_utils/nested_result_base'
|
4
|
-
require 'skn_utils/generic_bean'
|
5
|
-
require 'skn_utils/page_controls'
|
6
|
-
require 'skn_utils/result_bean'
|
7
|
-
require 'skn_utils/value_bean'
|
2
|
+
require 'skn_utils/nested_result'
|
8
3
|
require 'skn_utils/null_object'
|
9
4
|
require 'skn_utils/exploring/commander'
|
10
5
|
require 'skn_utils/exploring/action_service'
|
data/skn_utils.gemspec
CHANGED
@@ -9,28 +9,11 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.author = 'James Scott Jr'
|
10
10
|
spec.email = 'skoona@gmail.com'
|
11
11
|
spec.summary = <<EOF
|
12
|
-
Ruby
|
13
|
-
|
14
|
-
|
15
|
-
ResultBean is a PORO (Plain Old Ruby Object) which inherits from NestedResultBean class (inlcuded). This class
|
16
|
-
is instantiated via a hash at Ruby Runtime, allowing access to vars via dot or hash notation,
|
17
|
-
and is serializable (<obj>.to_hash) using standard Hash serialization methods.
|
12
|
+
SknUtils contains a small collection of Ruby utilities, the first being a NestedResult a key/value container.
|
18
13
|
EOF
|
19
14
|
|
20
15
|
spec.description = <<EOF
|
21
|
-
|
22
|
-
If a key's value is also a hash, it too can optionally become an Object.
|
23
|
-
If a key's value is a Array of Hashes, each element of the Array can optionally become an Object.
|
24
|
-
|
25
|
-
|
26
|
-
This nesting action is controlled by the value of the options key ':depth'. Options key :depth defaults
|
27
|
-
to :multi, and has options of :single, :multi, or :multi_with_arrays
|
28
|
-
|
29
|
-
|
30
|
-
The ability of the resulting Object to be Marshalled(dump/load) can be preserved by merging configuration options
|
31
|
-
into the input params. Key ':enable_serialization' set to true. It defaults to false for speed purposes.
|
32
|
-
|
33
|
-
|
16
|
+
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).
|
34
17
|
Review the RSpec tests, and or review the README for more details.
|
35
18
|
EOF
|
36
19
|
|
@@ -46,7 +29,8 @@ EOF
|
|
46
29
|
spec.add_development_dependency "rake", ">= 0"
|
47
30
|
spec.add_development_dependency "rspec", '~> 3.0'
|
48
31
|
spec.add_development_dependency "pry", ">= 0"
|
49
|
-
|
32
|
+
spec.add_development_dependency "simplecov", ">= 0"
|
33
|
+
|
50
34
|
## Make sure you can build the gem on older versions of RubyGems too:
|
51
35
|
spec.rubygems_version = "1.6.2"
|
52
36
|
spec.required_rubygems_version = Gem::Requirement.new(">= 0") if spec.respond_to? :required_rubygems_version=
|