pakyow-support 0.11.3 → 1.0.0.rc1
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 +5 -5
- data/{pakyow-support/CHANGELOG.md → CHANGELOG.md} +4 -0
- data/LICENSE +4 -0
- data/{pakyow-support/README.md → README.md} +1 -2
- data/lib/pakyow/support/aargv.rb +25 -0
- data/lib/pakyow/support/bindable.rb +19 -0
- data/lib/pakyow/support/class_state.rb +49 -0
- data/lib/pakyow/support/cli/runner.rb +106 -0
- data/lib/pakyow/support/cli/style.rb +13 -0
- data/lib/pakyow/support/configurable/config.rb +153 -0
- data/lib/pakyow/support/configurable/setting.rb +52 -0
- data/lib/pakyow/support/configurable.rb +103 -0
- data/lib/pakyow/support/core_refinements/array/ensurable.rb +25 -0
- data/lib/pakyow/support/core_refinements/method/introspection.rb +21 -0
- data/lib/pakyow/support/core_refinements/proc/introspection.rb +21 -0
- data/lib/pakyow/support/core_refinements/string/normalization.rb +50 -0
- data/lib/pakyow/support/deep_dup.rb +61 -0
- data/lib/pakyow/support/deep_freeze.rb +82 -0
- data/lib/pakyow/support/definable.rb +242 -0
- data/lib/pakyow/support/dependencies.rb +61 -0
- data/lib/pakyow/support/extension.rb +82 -0
- data/lib/pakyow/support/hookable.rb +227 -0
- data/lib/pakyow/support/indifferentize.rb +183 -0
- data/lib/pakyow/support/inflector.rb +13 -0
- data/lib/pakyow/support/inspectable.rb +88 -0
- data/lib/pakyow/support/logging.rb +31 -0
- data/lib/pakyow/support/makeable/object_maker.rb +30 -0
- data/lib/pakyow/support/makeable/object_name.rb +45 -0
- data/lib/pakyow/support/makeable/object_namespace.rb +28 -0
- data/lib/pakyow/support/makeable.rb +117 -0
- data/lib/pakyow/support/message_verifier.rb +74 -0
- data/lib/pakyow/support/path_version.rb +21 -0
- data/lib/pakyow/support/pipeline/object.rb +41 -0
- data/lib/pakyow/support/pipeline.rb +335 -0
- data/lib/pakyow/support/safe_string.rb +60 -0
- data/lib/pakyow/support/serializer.rb +49 -0
- data/lib/pakyow/support/silenceable.rb +21 -0
- data/lib/pakyow/support/string_builder.rb +62 -0
- data/lib/pakyow/support.rb +1 -0
- metadata +107 -26
- data/pakyow-support/LICENSE +0 -20
- data/pakyow-support/lib/pakyow/support/aargv.rb +0 -15
- data/pakyow-support/lib/pakyow/support/array.rb +0 -9
- data/pakyow-support/lib/pakyow/support/dir.rb +0 -32
- data/pakyow-support/lib/pakyow/support/dup.rb +0 -23
- data/pakyow-support/lib/pakyow/support/file.rb +0 -5
- data/pakyow-support/lib/pakyow/support/hash.rb +0 -47
- data/pakyow-support/lib/pakyow/support/kernel.rb +0 -9
- data/pakyow-support/lib/pakyow/support/string.rb +0 -36
- data/pakyow-support/lib/pakyow/support.rb +0 -8
- data/pakyow-support/lib/pakyow-support.rb +0 -1
@@ -0,0 +1,227 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/class_state"
|
4
|
+
|
5
|
+
module Pakyow
|
6
|
+
module Support
|
7
|
+
# Makes it possible to define and call hooks on an object.
|
8
|
+
#
|
9
|
+
# Hooks can be defined at the class or instance level. When calling hooks
|
10
|
+
# on an instance, hooks defined on the class will be called first.
|
11
|
+
#
|
12
|
+
# By default, hooks are called in the order they are defined. Each hook
|
13
|
+
# can be assigned a relative priority to influence when it is to be called
|
14
|
+
# (relative to other hooks of the same type). Default hook priority is `0`,
|
15
|
+
# and can instead be set to `1` (high) or `-1` (low).
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
# class Fish
|
19
|
+
# include Pakyow::Support::Hookable
|
20
|
+
# events :swim
|
21
|
+
#
|
22
|
+
# def swim
|
23
|
+
# performing "swim" do
|
24
|
+
# puts "swimming"
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# Fish.before "swim" do
|
30
|
+
# puts "prepping"
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# fish = Fish.new
|
34
|
+
#
|
35
|
+
# fish.after "swim" do
|
36
|
+
# puts "resting"
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# fish.swim
|
40
|
+
# => prepping
|
41
|
+
# swimming
|
42
|
+
# resting
|
43
|
+
#
|
44
|
+
module Hookable
|
45
|
+
# Known hook priorities.
|
46
|
+
#
|
47
|
+
PRIORITIES = { default: 0, high: 1, low: -1 }.freeze
|
48
|
+
|
49
|
+
def self.included(base)
|
50
|
+
base.include CommonMethods
|
51
|
+
base.include InstanceMethods
|
52
|
+
|
53
|
+
base.extend ClassMethods
|
54
|
+
|
55
|
+
base.extend ClassState
|
56
|
+
base.class_state :__events, default: [], inheritable: true, getter: false
|
57
|
+
base.class_state :__hooks, default: [], inheritable: true, getter: false
|
58
|
+
base.class_state :__hook_hash, default: { after: {}, before: {} }, inheritable: true
|
59
|
+
base.class_state :__hook_pipeline, default: { after: {}, before: {} }, inheritable: true
|
60
|
+
end
|
61
|
+
|
62
|
+
# @api private
|
63
|
+
def known_event?(event)
|
64
|
+
self.class.known_event?(event.to_sym)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Class-level api methods.
|
68
|
+
#
|
69
|
+
module ClassMethods
|
70
|
+
attr_reader :__hook_pipeline
|
71
|
+
|
72
|
+
def self.extended(base)
|
73
|
+
base.extend(CommonMethods)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Sets the known events for the hookable object. Hooks registered for
|
77
|
+
# an event that doesn't exist will raise an ArgumentError.
|
78
|
+
#
|
79
|
+
# @param events [Array<Symbol>] The list of known events.
|
80
|
+
#
|
81
|
+
def events(*events)
|
82
|
+
@__events.concat(events.map(&:to_sym)).uniq!; @__events
|
83
|
+
end
|
84
|
+
|
85
|
+
# Defines a hook to call before event occurs.
|
86
|
+
#
|
87
|
+
# @param event [Symbol] The name of the event.
|
88
|
+
# @param priority [Symbol, Integer] The priority of the hook.
|
89
|
+
# Other priorities include:
|
90
|
+
# high (1)
|
91
|
+
# low (-1)
|
92
|
+
#
|
93
|
+
def before(event, name = nil, priority: PRIORITIES[:default], exec: true, &block)
|
94
|
+
add_hook(:before, event, name, priority, exec, block)
|
95
|
+
end
|
96
|
+
alias on before
|
97
|
+
|
98
|
+
# Defines a hook to call after event occurs.
|
99
|
+
#
|
100
|
+
# @see #before
|
101
|
+
#
|
102
|
+
def after(event, name = nil, priority: PRIORITIES[:default], exec: true, &block)
|
103
|
+
add_hook(:after, event, name, priority, exec, block)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Defines a hook to call before and after event occurs.
|
107
|
+
#
|
108
|
+
# @see #before
|
109
|
+
#
|
110
|
+
def around(event, name = nil, priority: PRIORITIES[:default], exec: true, &block)
|
111
|
+
add_hook(:before, event, name, priority, exec, block)
|
112
|
+
add_hook(:after, event, name, priority, exec, block)
|
113
|
+
end
|
114
|
+
|
115
|
+
# @api private
|
116
|
+
def known_event?(event)
|
117
|
+
@__events.include?(event.to_sym)
|
118
|
+
end
|
119
|
+
|
120
|
+
def known_hook?(event)
|
121
|
+
@__hooks.any? { |hook|
|
122
|
+
hook[:name] == event.to_sym
|
123
|
+
}
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Methods included at the class and instance level.
|
128
|
+
#
|
129
|
+
module CommonMethods
|
130
|
+
# Calls all registered hooks for `event`, yielding between them.
|
131
|
+
#
|
132
|
+
# @param event [Symbol] The name of the event.
|
133
|
+
#
|
134
|
+
def performing(event, *args)
|
135
|
+
call_hooks(:before, event, *args)
|
136
|
+
value = yield
|
137
|
+
call_hooks(:after, event, *args)
|
138
|
+
value
|
139
|
+
end
|
140
|
+
|
141
|
+
# Calls all registered hooks of type, for event.
|
142
|
+
#
|
143
|
+
# @param type [Symbol] The type of event (e.g. before / after).
|
144
|
+
# @param event [Symbol] The name of the event.
|
145
|
+
#
|
146
|
+
def call_hooks(type, event, *args)
|
147
|
+
hooks(type, event).each do |hook|
|
148
|
+
if hook[:exec]
|
149
|
+
instance_exec(*args, &hook[:block])
|
150
|
+
else
|
151
|
+
hook[:block].call(*args)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# @api private
|
157
|
+
def hooks(type, event)
|
158
|
+
__hook_pipeline[type][event] || []
|
159
|
+
end
|
160
|
+
|
161
|
+
# @api private
|
162
|
+
def add_hook(type, event, name, priority, exec, hook)
|
163
|
+
if priority.is_a?(Symbol)
|
164
|
+
priority = PRIORITIES[priority]
|
165
|
+
end
|
166
|
+
|
167
|
+
if known_event?(event) || known_hook?(event)
|
168
|
+
hook = {
|
169
|
+
type: type,
|
170
|
+
event: event.to_sym,
|
171
|
+
name: name ? name.to_sym : nil,
|
172
|
+
priority: priority,
|
173
|
+
block: hook,
|
174
|
+
exec: exec
|
175
|
+
}
|
176
|
+
|
177
|
+
(@__hook_hash[type.to_sym][event.to_sym] ||= []) << hook
|
178
|
+
@__hooks << hook
|
179
|
+
else
|
180
|
+
raise ArgumentError, "#{event} is not a known hook event"
|
181
|
+
end
|
182
|
+
|
183
|
+
reprioritize!(type, event)
|
184
|
+
pipeline!(type, event)
|
185
|
+
|
186
|
+
if known_hook?(event)
|
187
|
+
traverse_events_for_hook(event) do |hook_event|
|
188
|
+
pipeline!(:before, hook_event); pipeline!(:after, hook_event)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
# @api private
|
194
|
+
def traverse_events_for_hook(name, &block)
|
195
|
+
if hook = @__hooks.find { |h| h[:name] == name.to_sym }
|
196
|
+
yield hook[:event]
|
197
|
+
traverse_events_for_hook(hook[:event], &block)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
# @api private
|
202
|
+
def reprioritize!(type, event)
|
203
|
+
@__hook_hash[type.to_sym][event.to_sym] = @__hook_hash[type.to_sym][event.to_sym].group_by { |hook|
|
204
|
+
hook[:priority]
|
205
|
+
}.sort { |a, b|
|
206
|
+
b[0] <=> a[0]
|
207
|
+
}.flat_map { |group|
|
208
|
+
group[1]
|
209
|
+
}
|
210
|
+
end
|
211
|
+
|
212
|
+
# @api private
|
213
|
+
def pipeline!(type, event)
|
214
|
+
__hook_pipeline[type.to_sym][event.to_sym] = @__hook_hash.dig(type.to_sym, event.to_sym).to_a.flat_map { |hook|
|
215
|
+
[@__hook_pipeline[:before][hook[:name]].to_a, hook, @__hook_pipeline[:after][hook[:name]].to_a].flatten
|
216
|
+
}
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
module InstanceMethods
|
221
|
+
def __hook_pipeline
|
222
|
+
self.class.__hook_pipeline
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "delegate"
|
4
|
+
|
5
|
+
module Pakyow
|
6
|
+
module Support
|
7
|
+
# Creates a Hash-like object can access stored data with symbol or
|
8
|
+
# string keys.
|
9
|
+
#
|
10
|
+
# The original hash is converted to symbol keys, which means
|
11
|
+
# that a hash that originally contains a symbol and string key
|
12
|
+
# with the same symbold value will conflict. It is not guaranteed
|
13
|
+
# which value will be saved.
|
14
|
+
#
|
15
|
+
# IndifferentHash instances have the same api as Hash, but any method
|
16
|
+
# that would return a Hash, will return an IndifferentHash (with
|
17
|
+
# the exception of to_h/to_hash).
|
18
|
+
#
|
19
|
+
# NOTE: Please lookup Ruby's documentation for Hash to learn what
|
20
|
+
# methods are available.
|
21
|
+
#
|
22
|
+
# @example
|
23
|
+
# { test: "test1", "test" => "test2" } => { test: "test2" }
|
24
|
+
#
|
25
|
+
class IndifferentHash < SimpleDelegator
|
26
|
+
class << self
|
27
|
+
def deep(object)
|
28
|
+
hash = object.to_h
|
29
|
+
unless hash.empty?
|
30
|
+
hash = hash.each_with_object({}) { |(key, value), new_hash|
|
31
|
+
new_hash[key] = case value
|
32
|
+
when Hash
|
33
|
+
deep(value)
|
34
|
+
when Array
|
35
|
+
value.map { |value_item|
|
36
|
+
case value_item
|
37
|
+
when Hash
|
38
|
+
deep(value_item)
|
39
|
+
else
|
40
|
+
value_item
|
41
|
+
end
|
42
|
+
}
|
43
|
+
else
|
44
|
+
value
|
45
|
+
end
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
self.new(hash)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def indifferent_key_method(*methods)
|
55
|
+
methods.each do |name|
|
56
|
+
define_method(name) do |key = nil, *args, &block|
|
57
|
+
key = convert_key(key)
|
58
|
+
internal_hash.public_send(name, key, *args, &block)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def indifferent_multi_key_method(*methods)
|
64
|
+
methods.each do |name|
|
65
|
+
define_method(name) do |*keys, &block|
|
66
|
+
keys = keys.map { |key|
|
67
|
+
convert_key(key)
|
68
|
+
}
|
69
|
+
internal_hash.public_send(name, *keys, &block)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def indifferentize_return_method(*methods)
|
75
|
+
methods.each do |name|
|
76
|
+
define_method(name) do |*args, &block|
|
77
|
+
hash = internal_hash.public_send(name, *args, &block)
|
78
|
+
self.class.new(hash) if hash
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def indifferentize_update_method(*methods)
|
84
|
+
methods.each do |name|
|
85
|
+
define_method(name) do |*args, &block|
|
86
|
+
args = args.map { |arg| stringify_keys(arg) }
|
87
|
+
hash = internal_hash.public_send(name, *args, &block)
|
88
|
+
self if hash
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def indifferentize_argument_method(*methods)
|
94
|
+
methods.each do |name|
|
95
|
+
define_method(name) do |*args, &block|
|
96
|
+
args = args.map { |arg| stringify_keys(arg) }
|
97
|
+
internal_hash.public_send(name, *args, &block)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def initialize(hash = {})
|
104
|
+
self.internal_hash = hash
|
105
|
+
end
|
106
|
+
|
107
|
+
indifferent_key_method :[], :[]=, :default, :delete, :fetch, :has_key?, :key?, :include?, :member?, :store
|
108
|
+
indifferent_multi_key_method :fetch_values, :values_at, :dig
|
109
|
+
indifferentize_return_method :merge, :invert, :compact, :reject, :select, :transform_values
|
110
|
+
indifferentize_update_method :merge!, :update, :replace, :clear, :keep_if, :delete_if, :compact!, :reject!, :select!
|
111
|
+
indifferentize_argument_method :>, :>=, :<=>, :<, :<=, :==
|
112
|
+
|
113
|
+
def internal_hash
|
114
|
+
__getobj__
|
115
|
+
end
|
116
|
+
|
117
|
+
def to_h
|
118
|
+
internal_hash.each_with_object({}) { |(key, value), new_hash|
|
119
|
+
key = case key
|
120
|
+
when String
|
121
|
+
key.to_sym
|
122
|
+
else
|
123
|
+
key
|
124
|
+
end
|
125
|
+
|
126
|
+
value = case value
|
127
|
+
when IndifferentHash
|
128
|
+
value.to_h
|
129
|
+
else
|
130
|
+
value
|
131
|
+
end
|
132
|
+
|
133
|
+
new_hash[key] = value
|
134
|
+
}
|
135
|
+
end
|
136
|
+
alias to_hash to_h
|
137
|
+
|
138
|
+
# Fixes an issue using pp inside a delegator.
|
139
|
+
#
|
140
|
+
def pp(*args)
|
141
|
+
Kernel.pp(*args)
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
|
146
|
+
def internal_hash=(other)
|
147
|
+
__setobj__(stringify_keys(other))
|
148
|
+
end
|
149
|
+
|
150
|
+
def stringify_keys(object)
|
151
|
+
return object unless object.respond_to?(:to_h)
|
152
|
+
|
153
|
+
converted = {}
|
154
|
+
object.to_h.each do |key, value|
|
155
|
+
converted[convert_key(key)] = value
|
156
|
+
end
|
157
|
+
|
158
|
+
converted
|
159
|
+
end
|
160
|
+
|
161
|
+
def convert_key(key)
|
162
|
+
case key
|
163
|
+
when Symbol
|
164
|
+
key.to_s
|
165
|
+
else
|
166
|
+
key
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
module Indifferentize
|
172
|
+
refine Hash do
|
173
|
+
def indifferentize
|
174
|
+
Pakyow::Support::IndifferentHash.new(self)
|
175
|
+
end
|
176
|
+
|
177
|
+
def deep_indifferentize
|
178
|
+
Pakyow::Support::IndifferentHash.deep(self)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/class_state"
|
4
|
+
|
5
|
+
module Pakyow
|
6
|
+
module Support
|
7
|
+
# Customized inspectors for your objects.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# class FooBar
|
11
|
+
# include Pakyow::Support::Inspectable
|
12
|
+
# inspectable :@foo, :baz
|
13
|
+
#
|
14
|
+
# def initialize
|
15
|
+
# @foo = :foo
|
16
|
+
# @bar = :bar
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# def baz
|
20
|
+
# :baz
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# FooBar.instance.inspect
|
25
|
+
# => #<FooBar:0x007fd3330248c0 @foo=:foo baz=:baz>
|
26
|
+
#
|
27
|
+
module Inspectable
|
28
|
+
def self.included(base)
|
29
|
+
base.extend ClassMethods
|
30
|
+
base.extend ClassState unless base.ancestors.include?(ClassState)
|
31
|
+
base.class_state :__inspectables, inheritable: true, default: []
|
32
|
+
end
|
33
|
+
|
34
|
+
module ClassMethods
|
35
|
+
# Sets the instance vars and public methods that should be part of the inspection.
|
36
|
+
#
|
37
|
+
# @param inspectables [Array<Symbol>] The list of instance variables and public methods.
|
38
|
+
#
|
39
|
+
def inspectable(*inspectables)
|
40
|
+
@__inspectables = inspectables.map(&:to_sym)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Recursion protection based on:
|
45
|
+
# https://stackoverflow.com/a/5772445
|
46
|
+
#
|
47
|
+
def inspect
|
48
|
+
inspection = String.new("#<#{self.class}:#{self.object_id}")
|
49
|
+
|
50
|
+
if recursive_inspect?
|
51
|
+
"#{inspection} ...>"
|
52
|
+
else
|
53
|
+
prevent_inspect_recursion do
|
54
|
+
if self.class.__inspectables.any?
|
55
|
+
inspection << " " + self.class.__inspectables.map { |inspectable|
|
56
|
+
value = if inspectable.to_s.start_with?("@")
|
57
|
+
instance_variable_get(inspectable)
|
58
|
+
else
|
59
|
+
send(inspectable)
|
60
|
+
end
|
61
|
+
|
62
|
+
"#{inspectable}=#{value.inspect}"
|
63
|
+
}.join(", ")
|
64
|
+
end
|
65
|
+
|
66
|
+
inspection.strip << ">"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def inspected_objects
|
74
|
+
Thread.current[:inspected_objects] ||= {}
|
75
|
+
end
|
76
|
+
|
77
|
+
def prevent_inspect_recursion
|
78
|
+
inspected_objects[object_id] = true; yield
|
79
|
+
ensure
|
80
|
+
inspected_objects.delete(object_id)
|
81
|
+
end
|
82
|
+
|
83
|
+
def recursive_inspect?
|
84
|
+
inspected_objects[object_id]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "logger"
|
4
|
+
|
5
|
+
module Pakyow
|
6
|
+
module Support
|
7
|
+
module Logging
|
8
|
+
# Yields Pakyow.logger if defined, otherwise raises `error`.
|
9
|
+
#
|
10
|
+
def self.yield_or_raise(error)
|
11
|
+
if defined?(Pakyow.logger)
|
12
|
+
yield(Pakyow.logger)
|
13
|
+
else
|
14
|
+
raise error
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Yields Pakyow.logger if defined, or a default logger.
|
19
|
+
#
|
20
|
+
def self.safe
|
21
|
+
logger = if defined?(Pakyow.logger) && Pakyow.logger
|
22
|
+
Pakyow.logger
|
23
|
+
else
|
24
|
+
::Logger.new($stdout)
|
25
|
+
end
|
26
|
+
|
27
|
+
yield logger
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/inflector"
|
4
|
+
|
5
|
+
module Pakyow
|
6
|
+
module Support
|
7
|
+
# @api private
|
8
|
+
module ObjectMaker
|
9
|
+
def self.define_const_for_object_with_name(object_to_define, object_name)
|
10
|
+
return if object_name.nil?
|
11
|
+
|
12
|
+
target = object_name.namespace.parts.inject(Object) { |target_for_part, object_name_part|
|
13
|
+
ObjectMaker.define_object_on_target_with_constant_name(Module.new, target_for_part, object_name_part)
|
14
|
+
}
|
15
|
+
|
16
|
+
ObjectMaker.define_object_on_target_with_constant_name(object_to_define, target, object_name.name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.define_object_on_target_with_constant_name(object, target, constant_name)
|
20
|
+
constant_name = Support.inflector.camelize(constant_name)
|
21
|
+
|
22
|
+
unless target.const_defined?(constant_name, false)
|
23
|
+
target.const_set(constant_name, object)
|
24
|
+
end
|
25
|
+
|
26
|
+
target.const_get(constant_name)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/inflector"
|
4
|
+
require "pakyow/support/makeable/object_namespace"
|
5
|
+
|
6
|
+
module Pakyow
|
7
|
+
module Support
|
8
|
+
# @api private
|
9
|
+
class ObjectName
|
10
|
+
class << self
|
11
|
+
def namespace(*namespaces, object_name)
|
12
|
+
ObjectName.new(
|
13
|
+
ObjectNamespace.new(*namespaces),
|
14
|
+
object_name
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :namespace, :name
|
20
|
+
|
21
|
+
def initialize(namespace, name)
|
22
|
+
@namespace, @name = namespace, name.to_sym
|
23
|
+
end
|
24
|
+
|
25
|
+
def isolated(subobject_name)
|
26
|
+
ObjectName.new(
|
27
|
+
ObjectNamespace.new(*parts),
|
28
|
+
subobject_name
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def parts
|
33
|
+
namespace.parts + [@name]
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
[@namespace, @name].join("/")
|
38
|
+
end
|
39
|
+
|
40
|
+
def constant
|
41
|
+
[@namespace.constant, Support.inflector.camelize(@name)].join("::")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/inflector"
|
4
|
+
|
5
|
+
module Pakyow
|
6
|
+
module Support
|
7
|
+
# @api private
|
8
|
+
class ObjectNamespace
|
9
|
+
def initialize(*namespaces)
|
10
|
+
@namespaces = namespaces.map(&:to_sym)
|
11
|
+
end
|
12
|
+
|
13
|
+
def parts
|
14
|
+
@namespaces
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
@namespaces.join("/")
|
19
|
+
end
|
20
|
+
|
21
|
+
def constant
|
22
|
+
@namespaces.map { |namespace|
|
23
|
+
Support.inflector.camelize(namespace)
|
24
|
+
}.join("::")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|