skn_utils 3.5.2 → 3.6.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/README.md +10 -83
- data/_config.yml +24 -1
- data/bin/console +0 -4
- data/lib/skn_utils/nested_result.rb +5 -5
- data/lib/skn_utils/version.rb +2 -2
- data/lib/skn_utils.rb +2 -18
- data/skn_utils.gemspec +0 -6
- data/spec/spec_helper.rb +0 -4
- metadata +3 -49
- data/lib/skn_utils/business_services/year_month.rb +0 -58
- data/lib/skn_utils/converters/hash_to_xml.rb +0 -98
- data/lib/skn_utils/exploring/action_service.rb +0 -90
- data/lib/skn_utils/exploring/commander.rb +0 -68
- data/lib/skn_utils/exploring/configuration.rb +0 -53
- data/lib/skn_utils/lists/circular_linked_list.rb +0 -161
- data/lib/skn_utils/lists/doubly_linked_list.rb +0 -139
- data/lib/skn_utils/lists/link_node.rb +0 -103
- data/lib/skn_utils/lists/linked_commons.rb +0 -216
- data/lib/skn_utils/lists/linked_list.rb +0 -122
- data/spec/lib/skn_utils/business_services/year_month_spec.rb +0 -49
- data/spec/lib/skn_utils/converters/hash_to_xml_spec.rb +0 -120
- data/spec/lib/skn_utils/exploring/action_service_spec.rb +0 -40
- data/spec/lib/skn_utils/exploring/commander_spec.rb +0 -125
- data/spec/lib/skn_utils/exploring/configuration_spec.rb +0 -52
- data/spec/lib/skn_utils/lists/Circular_linked_list_spec.rb +0 -184
- data/spec/lib/skn_utils/lists/doubly_linked_list_spec.rb +0 -182
- data/spec/lib/skn_utils/lists/linked_list_spec.rb +0 -155
- data/spec/lib/skn_utils/lists/node_based_linked_list_spec.rb +0 -86
- data/spec/support/shared_examples_for_linked_list.rb +0 -156
@@ -1,68 +0,0 @@
|
|
1
|
-
##
|
2
|
-
# <project.root>/lib/skn_utils/exploring/commander.rb
|
3
|
-
##
|
4
|
-
# ref: https://github.com/saturnflyer/direction
|
5
|
-
##
|
6
|
-
# Provide a feature like the Forwardable library,
|
7
|
-
# but set the return value to self.
|
8
|
-
# It provides a class level "command" method to do
|
9
|
-
# message forwarding.
|
10
|
-
#
|
11
|
-
# class SomeClass
|
12
|
-
# extend SknUtils::Commander
|
13
|
-
#
|
14
|
-
# command [:print_details, :setup_things] => :collaborator
|
15
|
-
# query [:name, :id] => :collaborator, :type => :@partner
|
16
|
-
# end
|
17
|
-
#
|
18
|
-
# This will define methods on instances that forward to the
|
19
|
-
# provided receiver while enforcing encapsulation of the
|
20
|
-
# relationship between objects.
|
21
|
-
#
|
22
|
-
# the collaborator and you must agree on how results can be exchanged
|
23
|
-
# you might provide a callback method for it to set its return value on you
|
24
|
-
# :callback, develop a protocol to exchange messages with collaborator
|
25
|
-
##
|
26
|
-
|
27
|
-
|
28
|
-
module SknUtils
|
29
|
-
module Exploring
|
30
|
-
module Commander
|
31
|
-
|
32
|
-
# Forward messages and return self, protecting the encapsulation of the object
|
33
|
-
def command(options)
|
34
|
-
Commander.define_methods(self, options) do |command, accessor|
|
35
|
-
%{
|
36
|
-
def #{command}(*args, &block)
|
37
|
-
#{accessor}.__send__(:#{command}, *args, &block)
|
38
|
-
self
|
39
|
-
end
|
40
|
-
}
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
# Forward messages and return the result of the forwarded message
|
45
|
-
def query(options)
|
46
|
-
Commander.define_methods(self, options) do |query, accessor|
|
47
|
-
%{
|
48
|
-
def #{query}(*args, &block)
|
49
|
-
#{accessor}.__send__(:#{query}, *args, &block)
|
50
|
-
end
|
51
|
-
}
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# Commander's class method
|
56
|
-
def self.define_methods(mod, options)
|
57
|
-
method_defs = []
|
58
|
-
options.each_pair do |method_names, accessor|
|
59
|
-
Array(method_names).map do |message|
|
60
|
-
method_defs.push yield(message, accessor)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
mod.class_eval method_defs.join("\n"), __FILE__, __LINE__
|
64
|
-
end
|
65
|
-
|
66
|
-
end # Commander
|
67
|
-
end # Exploring
|
68
|
-
end # SknUtils
|
@@ -1,53 +0,0 @@
|
|
1
|
-
##
|
2
|
-
# File: <gem-root>/lib/skn_utils/exploring/configuration.rb
|
3
|
-
#
|
4
|
-
# Engines and Gem sometimes need a configuration object, this is an example
|
5
|
-
# Options class, consider OpenStruct2 or ActiveSupport::OrderedOptions as alternatives
|
6
|
-
|
7
|
-
module SknUtils
|
8
|
-
module Exploring
|
9
|
-
module Configuration
|
10
|
-
|
11
|
-
module_function
|
12
|
-
|
13
|
-
def option_defaults
|
14
|
-
@option_defaults ||= {one: 1, two: 2, three: 3}
|
15
|
-
end
|
16
|
-
def option_defaults=(parms)
|
17
|
-
@option_defaults = parms
|
18
|
-
end
|
19
|
-
|
20
|
-
def reset!
|
21
|
-
@configuration = Options.new(option_defaults)
|
22
|
-
true
|
23
|
-
end
|
24
|
-
|
25
|
-
def config
|
26
|
-
configure
|
27
|
-
end
|
28
|
-
|
29
|
-
def configure # Initialize with both the configuration keys and default values
|
30
|
-
@configuration || reset!
|
31
|
-
yield(@configuration) if block_given?
|
32
|
-
@configuration
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
class Options
|
38
|
-
def initialize(parms={})
|
39
|
-
parms.each_pair do |k,v|
|
40
|
-
self.singleton_class.send(:attr_accessor, k)
|
41
|
-
instance_variable_set("@#{k}",v)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
47
|
-
# require your Gem or Engine here
|
48
|
-
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# In config/initializers/gem_config.rb
|
53
|
-
# SknUtils::Exploring::Configuration.class_variable_set(:option_defaults, {one: 1, two: 2, three: 3})
|
@@ -1,161 +0,0 @@
|
|
1
|
-
##
|
2
|
-
# File <SknUtils>/lib/skn_utils/lists/circular_linked_list.rb
|
3
|
-
#
|
4
|
-
# ll = SknUtils::Lists::CircularLinkedList.new(*vargs, &compare_key_proc)
|
5
|
-
# - or -
|
6
|
-
# ll = SknUtils::Lists::CircularLinkedList.new(1,2,3,4,5) {|element| element[:key] }
|
7
|
-
# - or -
|
8
|
-
# ll = SknUtils::Lists::CircularLinkedList.new(
|
9
|
-
# {key: 'Z'}, {key: 'K'}, {key: 'S'}, {key: 'n'}, {key: 's'}
|
10
|
-
# ) {|el| el[:key] }
|
11
|
-
# - or -
|
12
|
-
# cmp_proc = lambda { |el| el[:key] }
|
13
|
-
# vargs = [{key: 'Z'}, {key: 'K'}, {key: 'S'}, {key: 'n'}, {key: 's'}]
|
14
|
-
# ll = SknUtils::Lists::CircularLinkedList.new(*vargs, &cmp_proc)
|
15
|
-
###
|
16
|
-
# value = ll.first
|
17
|
-
# value = ll.at_index(4)
|
18
|
-
# count = ll.insert({key: 'anyValue'})
|
19
|
-
# ...
|
20
|
-
# count = ll.sort! -- defaults to :asc
|
21
|
-
# count = ll.sort!(:desc)
|
22
|
-
# count = ll.sort!() {|a,b| a[:key] <= b[:key] }
|
23
|
-
##
|
24
|
-
|
25
|
-
module SknUtils
|
26
|
-
module Lists
|
27
|
-
# Circularly Linked List
|
28
|
-
# Forward (#next) and Backwards (#prev) navigation
|
29
|
-
# No Head or Tail
|
30
|
-
|
31
|
-
# LinkedCommons provides;
|
32
|
-
# - #initialize, #first, #next, #current, #last, #at_index,
|
33
|
-
# #insert, #prepend, #append, #empty?, #clear,
|
34
|
-
# #each, #to_a, and #sort!
|
35
|
-
#
|
36
|
-
class CircularLinkedList < LinkedCommons
|
37
|
-
|
38
|
-
#
|
39
|
-
# Navigation
|
40
|
-
#
|
41
|
-
|
42
|
-
|
43
|
-
def prev
|
44
|
-
@current = @current.prev if @current and @current.prev
|
45
|
-
@current.value rescue nil
|
46
|
-
end
|
47
|
-
|
48
|
-
# -+ int position from current node
|
49
|
-
def nth(index)
|
50
|
-
node = @current
|
51
|
-
position = node
|
52
|
-
if index > 0
|
53
|
-
while index > 1 and node and node.next
|
54
|
-
node = node.next
|
55
|
-
index -= 1
|
56
|
-
@current = node
|
57
|
-
break if position.equal?(node)
|
58
|
-
end
|
59
|
-
elsif index < 0
|
60
|
-
while index < 0 and node and node.prev
|
61
|
-
node = node.prev
|
62
|
-
index += 1
|
63
|
-
@current = node
|
64
|
-
break if position.equal?(node)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
current
|
68
|
-
end
|
69
|
-
|
70
|
-
#
|
71
|
-
# Modifications
|
72
|
-
#
|
73
|
-
# return new size
|
74
|
-
def insert(value)
|
75
|
-
node = @current
|
76
|
-
@current = LinkNode.call(value, node, :circle_after, self, &@match_value)
|
77
|
-
if self.size == 0 # only
|
78
|
-
self.head = @current
|
79
|
-
self.tail = @current
|
80
|
-
elsif self.tail == node
|
81
|
-
self.tail = @current
|
82
|
-
@current.next = self.head
|
83
|
-
self.head.prev = @current
|
84
|
-
end
|
85
|
-
self.size += 1
|
86
|
-
end
|
87
|
-
alias_method :append, :insert
|
88
|
-
|
89
|
-
# return new size
|
90
|
-
def insert_before(position_value, value)
|
91
|
-
target = find_by_value(position_value)
|
92
|
-
node = LinkNode.call(value, target, :circle_before, self, &@match_value)
|
93
|
-
@current = node
|
94
|
-
if self.size == 0 # only
|
95
|
-
self.head = node
|
96
|
-
self.tail = node
|
97
|
-
elsif self.head == target # new head
|
98
|
-
self.head = node
|
99
|
-
node.prev = self.tail
|
100
|
-
self.tail.next = node
|
101
|
-
end
|
102
|
-
self.size += 1
|
103
|
-
end
|
104
|
-
|
105
|
-
# return new size
|
106
|
-
def insert_after(position_value, value)
|
107
|
-
target = find_by_value(position_value)
|
108
|
-
node = LinkNode.call(value, target, :circle_after, self, &@match_value)
|
109
|
-
@current = node
|
110
|
-
if self.size == 0 # only
|
111
|
-
self.head = node
|
112
|
-
self.tail = node
|
113
|
-
elsif self.tail == target
|
114
|
-
self.tail = node
|
115
|
-
node.next = self.head
|
116
|
-
self.head.prev = node
|
117
|
-
end
|
118
|
-
self.size += 1
|
119
|
-
end
|
120
|
-
|
121
|
-
# return remaining size
|
122
|
-
def remove(value)
|
123
|
-
target_node = find_by_value(value)
|
124
|
-
if target_node
|
125
|
-
if self.size == 1 # will become zero
|
126
|
-
@current = nil
|
127
|
-
self.head = nil
|
128
|
-
self.tail = nil
|
129
|
-
elsif target_node.equal?(self.head) # top
|
130
|
-
@current = target_node.next
|
131
|
-
@current.prev = target_node.prev
|
132
|
-
self.tail.next = @current
|
133
|
-
self.head = @current
|
134
|
-
elsif target_node.equal?(self.tail) # bottom
|
135
|
-
@current = target_node.prev
|
136
|
-
@current.next = target_node.next
|
137
|
-
self.head.prev = @current
|
138
|
-
self.tail = @current
|
139
|
-
else # middle
|
140
|
-
@current = target_node.prev
|
141
|
-
@current.next = target_node.next
|
142
|
-
@current.next.prev = @current
|
143
|
-
end
|
144
|
-
target_node.remove!
|
145
|
-
self.size -= 1
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
protected
|
150
|
-
|
151
|
-
def find_by_index(index)
|
152
|
-
return nil if ( index > self.size || index < 1 )
|
153
|
-
node = self.head
|
154
|
-
node = node.next while ( (index -= 1) > 0 )
|
155
|
-
@current = node
|
156
|
-
node
|
157
|
-
end
|
158
|
-
|
159
|
-
end # end class
|
160
|
-
end # module
|
161
|
-
end # end module
|
@@ -1,139 +0,0 @@
|
|
1
|
-
##
|
2
|
-
# File <SknUtils>/lib/skn_utils/lists/doubly_linked_list.rb
|
3
|
-
#
|
4
|
-
# ll = SknUtils::Lists::DoublyLinkedList.new(*vargs, &compare_key_proc)
|
5
|
-
# - or -
|
6
|
-
# ll = SknUtils::Lists::DoublyLinkedList.new(1,2,3,4,5) {|element| element[:key] }
|
7
|
-
# - or -
|
8
|
-
# ll = SknUtils::Lists::DoublyLinkedList.new(
|
9
|
-
# {key: 'Z'}, {key: 'K'}, {key: 'S'}, {key: 'n'}, {key: 's'}
|
10
|
-
# ) {|el| el[:key] }
|
11
|
-
# - or -
|
12
|
-
# cmp_proc = lambda { |el| el[:key] }
|
13
|
-
# vargs = [{key: 'Z'}, {key: 'K'}, {key: 'S'}, {key: 'n'}, {key: 's'}]
|
14
|
-
# ll = SknUtils::Lists::DoublyLinkedList.new(*vargs, &cmp_proc)
|
15
|
-
###
|
16
|
-
# value = ll.first
|
17
|
-
# value = ll.at_index(4)
|
18
|
-
# count = ll.insert({key: 'anyValue'})
|
19
|
-
# ...
|
20
|
-
# count = ll.sort! -- defaults to :asc
|
21
|
-
# count = ll.sort!(:desc)
|
22
|
-
# count = ll.sort!() {|a,b| a[:key] <= b[:key] }
|
23
|
-
##
|
24
|
-
|
25
|
-
module SknUtils
|
26
|
-
module Lists
|
27
|
-
# Doubly Linked List
|
28
|
-
# Forward (#next) and Backwards (#prev) navigation
|
29
|
-
# Head when (prev == nil)
|
30
|
-
# Tail when (next == nil)
|
31
|
-
|
32
|
-
# LinkedCommons provides;
|
33
|
-
# - #initialize, #first, #next, #current, #last, #at_index,
|
34
|
-
# #insert, #prepend, #append, #empty?, #clear,
|
35
|
-
# #each, #to_a, and #sort!
|
36
|
-
#
|
37
|
-
class DoublyLinkedList < LinkedCommons
|
38
|
-
|
39
|
-
#
|
40
|
-
# Navigation
|
41
|
-
#
|
42
|
-
|
43
|
-
def prev
|
44
|
-
@current = @current.prev if @current and @current.prev
|
45
|
-
@current.value rescue nil
|
46
|
-
end
|
47
|
-
|
48
|
-
# -+ int position from current node
|
49
|
-
def nth(index)
|
50
|
-
node = @current
|
51
|
-
if index > 0
|
52
|
-
while index > 1 and node and node.next
|
53
|
-
node = node.next
|
54
|
-
index -= 1
|
55
|
-
end
|
56
|
-
@current = node
|
57
|
-
elsif index < 0
|
58
|
-
while index < 0 and node and node.prev
|
59
|
-
node = node.prev
|
60
|
-
index += 1
|
61
|
-
end
|
62
|
-
@current = node
|
63
|
-
end
|
64
|
-
current
|
65
|
-
end
|
66
|
-
|
67
|
-
#
|
68
|
-
# Modifications
|
69
|
-
#
|
70
|
-
|
71
|
-
# return new size
|
72
|
-
def insert(value)
|
73
|
-
node = @current
|
74
|
-
@current = LinkNode.call(value, node, :after, self, &@match_value)
|
75
|
-
self.head = @current if self.head.nil?
|
76
|
-
self.tail = @current if self.tail.equal?(node)
|
77
|
-
self.size += 1
|
78
|
-
end
|
79
|
-
alias_method :append, :insert
|
80
|
-
|
81
|
-
# return new size
|
82
|
-
def insert_before(position_value, value)
|
83
|
-
target = find_by_value(position_value)
|
84
|
-
node = LinkNode.call(value, target, :before, self, &@match_value)
|
85
|
-
@current = node if target
|
86
|
-
self.head = node if self.head.equal?(target)
|
87
|
-
self.tail = node if self.tail.nil?
|
88
|
-
self.size += 1
|
89
|
-
end
|
90
|
-
|
91
|
-
# return new size
|
92
|
-
def insert_after(position_value, value)
|
93
|
-
target = find_by_value(position_value)
|
94
|
-
node = LinkNode.call(value, target, :after, self, &@match_value)
|
95
|
-
@current = node
|
96
|
-
self.head = node if self.head.nil?
|
97
|
-
self.tail = node if self.tail.equal?(target)
|
98
|
-
self.size += 1
|
99
|
-
end
|
100
|
-
|
101
|
-
# return remaining size
|
102
|
-
def remove(value)
|
103
|
-
target_node = find_by_value(value)
|
104
|
-
if target_node
|
105
|
-
if self.size == 1 # will become zero
|
106
|
-
@current = nil
|
107
|
-
self.head = nil
|
108
|
-
self.tail = nil
|
109
|
-
elsif target_node.prev.nil? # top
|
110
|
-
@current = target_node.next
|
111
|
-
@current.prev = nil
|
112
|
-
self.head = @current
|
113
|
-
elsif target_node.next.nil? # bottom
|
114
|
-
@current = target_node.prev
|
115
|
-
@current.next = nil
|
116
|
-
self.tail = @current
|
117
|
-
else # middle
|
118
|
-
@current = target_node.prev
|
119
|
-
@current.next = target_node.next
|
120
|
-
target_node.next.prev = @current
|
121
|
-
end
|
122
|
-
target_node.remove!
|
123
|
-
self.size -= 1
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
protected
|
128
|
-
|
129
|
-
def find_by_index(index)
|
130
|
-
return nil if self.head.nil? or index < 1 or index > self.size
|
131
|
-
node = self.head
|
132
|
-
node = node.next while ((index -= 1) > 0 and node.next)
|
133
|
-
@current = node if node
|
134
|
-
node
|
135
|
-
end
|
136
|
-
|
137
|
-
end # end class
|
138
|
-
end # module
|
139
|
-
end # end module
|
@@ -1,103 +0,0 @@
|
|
1
|
-
##
|
2
|
-
# Node.
|
3
|
-
# - primary object and container of value
|
4
|
-
##
|
5
|
-
|
6
|
-
module SknUtils
|
7
|
-
module Lists
|
8
|
-
|
9
|
-
class LinkNode
|
10
|
-
|
11
|
-
attr_accessor :prev, :next, :value
|
12
|
-
|
13
|
-
def self.call(val, anchor_node=nil, strategy=:after, mgr=nil, &cmp_key)
|
14
|
-
self.new(val, anchor_node, strategy, mgr, &cmp_key)
|
15
|
-
end
|
16
|
-
|
17
|
-
def initialize(val, anchor_node=nil, strategy=:after, mgr=nil, &cmp_key)
|
18
|
-
@value = val
|
19
|
-
@prev = nil
|
20
|
-
@next = nil
|
21
|
-
@provider = mgr
|
22
|
-
@cmp_proc = block_given? ? cmp_key : lambda {|a| a }
|
23
|
-
|
24
|
-
case strategy
|
25
|
-
when :single # after logic
|
26
|
-
if anchor_node
|
27
|
-
@next = anchor_node.next
|
28
|
-
anchor_node.next = self
|
29
|
-
end
|
30
|
-
when :before
|
31
|
-
@prev = anchor_node.prev if anchor_node
|
32
|
-
anchor_node.prev = self if anchor_node
|
33
|
-
@next = anchor_node
|
34
|
-
when :after
|
35
|
-
@next = anchor_node.next if anchor_node
|
36
|
-
anchor_node.next = self if anchor_node
|
37
|
-
@prev = anchor_node
|
38
|
-
when :circle_before
|
39
|
-
@prev = anchor_node ? anchor_node.prev : self
|
40
|
-
anchor_node.prev = self if anchor_node
|
41
|
-
@next = anchor_node ? anchor_node : self
|
42
|
-
when :circle_after
|
43
|
-
@next = anchor_node ? anchor_node.next : self
|
44
|
-
anchor_node.next = self if anchor_node
|
45
|
-
@prev = anchor_node ? anchor_node : self
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def match_by_value(other_value)
|
50
|
-
@cmp_proc.call(self.value) == @cmp_proc.call(other_value)
|
51
|
-
end
|
52
|
-
|
53
|
-
# returns next node
|
54
|
-
def remove!
|
55
|
-
next_node = @next
|
56
|
-
@value = nil
|
57
|
-
@prev = nil
|
58
|
-
@next = nil
|
59
|
-
@provider = nil
|
60
|
-
@cmp_proc = nil
|
61
|
-
next_node
|
62
|
-
end
|
63
|
-
|
64
|
-
def to_s
|
65
|
-
"Node with value: #{@value}"
|
66
|
-
end
|
67
|
-
|
68
|
-
# Reverse API to Parent Linked List Class
|
69
|
-
def node_value
|
70
|
-
node_value_request(:current)
|
71
|
-
end
|
72
|
-
def first_node
|
73
|
-
node_request(:first)
|
74
|
-
end
|
75
|
-
def next_node
|
76
|
-
node_request(:next)
|
77
|
-
end
|
78
|
-
def current_node
|
79
|
-
node_request(:current)
|
80
|
-
end
|
81
|
-
def prev_node
|
82
|
-
node_request(:prev)
|
83
|
-
end
|
84
|
-
def last_node
|
85
|
-
node_request(:last)
|
86
|
-
end
|
87
|
-
|
88
|
-
# Retrieves requested node, not value
|
89
|
-
def node_request(method_sym=:current, *vargs, &block)
|
90
|
-
block_given? ? @provider.send(method_sym, *vargs, &block) :
|
91
|
-
(vargs.size == 0 ? @provider.send(method_sym) : @provider.send(method_sym, *vargs))
|
92
|
-
@provider.instance_variable_get(:@current)
|
93
|
-
end
|
94
|
-
|
95
|
-
# Retrieves requested value, not node
|
96
|
-
def node_value_request(method_sym=:current, *vargs, &block)
|
97
|
-
block_given? ? @provider.send(method_sym, *vargs, &block) :
|
98
|
-
(vargs.size == 0 ? @provider.send(method_sym) : @provider.send(method_sym, *vargs))
|
99
|
-
end
|
100
|
-
|
101
|
-
end
|
102
|
-
end # module
|
103
|
-
end
|