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