sleeping_king_studios-tools 0.7.0.rc.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +46 -5
  3. data/CODE_OF_CONDUCT.md +132 -0
  4. data/DEVELOPMENT.md +7 -16
  5. data/LICENSE +1 -1
  6. data/README.md +71 -145
  7. data/lib/sleeping_king_studios/tools.rb +12 -6
  8. data/lib/sleeping_king_studios/tools/array_tools.rb +86 -58
  9. data/lib/sleeping_king_studios/tools/base.rb +20 -0
  10. data/lib/sleeping_king_studios/tools/core_tools.rb +78 -19
  11. data/lib/sleeping_king_studios/tools/hash_tools.rb +69 -42
  12. data/lib/sleeping_king_studios/tools/integer_tools.rb +97 -55
  13. data/lib/sleeping_king_studios/tools/object_tools.rb +75 -52
  14. data/lib/sleeping_king_studios/tools/string_tools.rb +69 -96
  15. data/lib/sleeping_king_studios/tools/toolbelt.rb +44 -23
  16. data/lib/sleeping_king_studios/tools/toolbox.rb +2 -2
  17. data/lib/sleeping_king_studios/tools/toolbox/constant_map.rb +75 -74
  18. data/lib/sleeping_king_studios/tools/toolbox/inflector.rb +124 -0
  19. data/lib/sleeping_king_studios/tools/toolbox/inflector/rules.rb +171 -0
  20. data/lib/sleeping_king_studios/tools/toolbox/mixin.rb +11 -11
  21. data/lib/sleeping_king_studios/tools/toolbox/semantic_version.rb +15 -14
  22. data/lib/sleeping_king_studios/tools/version.rb +15 -11
  23. metadata +105 -36
  24. data/lib/sleeping_king_studios/tools/all.rb +0 -5
  25. data/lib/sleeping_king_studios/tools/enumerable_tools.rb +0 -8
  26. data/lib/sleeping_king_studios/tools/semantic_version.rb +0 -15
  27. data/lib/sleeping_king_studios/tools/string_tools/plural_inflector.rb +0 -185
  28. data/lib/sleeping_king_studios/tools/toolbox/configuration.rb +0 -207
  29. data/lib/sleeping_king_studios/tools/toolbox/delegator.rb +0 -175
@@ -1,207 +0,0 @@
1
- # lib/sleeping_king_studios/tools/toolbox/configuration.rb
2
-
3
- require 'sleeping_king_studios/tools/toolbox'
4
-
5
- module SleepingKingStudios::Tools::Toolbox
6
- class Configuration
7
- module ClassMethods
8
- DEFAULT_OPTION = Object.new.freeze
9
-
10
- # Defines a nested namespace for the configuration object.
11
- def namespace namespace_name, &block
12
- namespace =
13
- (@namespaces ||= {}).fetch(namespace_name) do
14
- @namespaces[namespace_name] = define_namespace namespace_name
15
- end # fetch
16
-
17
- namespace.instance_exec namespace, &block if block_given?
18
-
19
- namespace
20
- end # method namespace
21
-
22
- # Defines an option for the configuration object.
23
- def option option_name, allow_nil: false, default: DEFAULT_OPTION, enum: nil
24
- options = {
25
- :allow_nil => allow_nil,
26
- :default => default,
27
- :enum => enum
28
- } # end hash
29
-
30
- define_accessor option_name, options
31
- define_mutator option_name, options
32
- end # class method option
33
-
34
- private
35
-
36
- def define_accessor option_name, options
37
- define_method option_name do
38
- __get_value__(option_name, options)
39
- end # method option_name
40
- end # method define_accessor
41
-
42
- def define_mutator option_name, options
43
- writer_name = :"#{option_name}="
44
-
45
- define_method writer_name do |value|
46
- __set_value__(option_name, value, options)
47
- end # method option_name=
48
- end # method define_mutator
49
-
50
- def define_namespace namespace_name
51
- namespace =
52
- Class.new(SleepingKingStudios::Tools::Toolbox::Configuration)
53
-
54
- define_method namespace_name do |&block|
55
- if instance_variable_defined?(:"@#{namespace_name}")
56
- config = instance_variable_get(:"@#{namespace_name}")
57
- else
58
- data = __get_value__(namespace_name, :default => Object.new)
59
- config = namespace.new(data)
60
-
61
- config.__root_namespace__ = __root_namespace__ || self
62
-
63
- instance_variable_set(:"@#{namespace_name}", config)
64
- end # if
65
-
66
- block.call(config) if block
67
-
68
- config
69
- end # method namespace_name
70
-
71
- namespace
72
- end # method define_namespace
73
- end # module
74
- extend ClassMethods
75
-
76
- DEFAULT_OPTION = ClassMethods::DEFAULT_OPTION
77
-
78
- # @param data [Hash, Object] The data source used to populate configuration
79
- # values. Can be a Hash or a data object. If the data source is nil, or no
80
- # data source is given, values will be set to their respective defaults.
81
- def initialize data = nil
82
- @__data__ = __objectify_data__(data)
83
- @__root_namespace__ = self
84
-
85
- yield(singleton_class) if block_given?
86
- end # constructor
87
-
88
- def [] key
89
- send(key) if respond_to?(key)
90
- end # method []
91
-
92
- def []= key, value
93
- send(:"#{key}=", value)
94
- end # method []=
95
-
96
- def dig *keys
97
- keys.reduce(self) do |hsh, key|
98
- value = hsh[key]
99
-
100
- return value if value.nil?
101
-
102
- value
103
- end # reduce
104
- end # method dig
105
-
106
- def fetch key, default = DEFAULT_OPTION
107
- return send(key) if respond_to?(key)
108
-
109
- return default unless default == DEFAULT_OPTION
110
-
111
- return yield if block_given?
112
-
113
- raise KeyError, 'key not found'
114
- end # method fetch
115
-
116
- protected
117
-
118
- attr_accessor :__root_namespace__
119
-
120
- private
121
-
122
- attr_reader :__data__
123
-
124
- def __blank_value__ value
125
- value.nil? || (value.respond_to?(:empty?) && value.empty?)
126
- end # method __blank_value__
127
-
128
- def __evaluate_default__ default
129
- default.is_a?(Proc) ? __root_namespace__.instance_exec(&default) : default
130
- end # method __evaluate_default__
131
-
132
- def __get_value__ name, options
133
- default_given = options[:default] != DEFAULT_OPTION
134
-
135
- if __data__.respond_to?(name)
136
- value = __data__.send name
137
-
138
- if value.nil? && default_given
139
- value = __evaluate_default__(options[:default])
140
- end # if
141
-
142
- __validate_value__ value, options
143
-
144
- value
145
- elsif instance_variable_defined?(:"@#{name}")
146
- # Recall values locally if data source is immutable.
147
- return instance_variable_get(:"@#{name}")
148
- elsif default_given
149
- value = __evaluate_default__(options[:default])
150
-
151
- __validate_value__ value, options
152
-
153
- value
154
- else
155
- __validate_value__ nil, options
156
-
157
- nil
158
- end # if-else
159
- end # method __get_value__
160
-
161
- def __objectify_data__ data
162
- return data unless data.is_a?(Hash)
163
-
164
- return Object.new if data.empty?
165
-
166
- obj = Struct.new(*data.keys).new
167
-
168
- data.each do |key, value|
169
- val = value.is_a?(Hash) ? __objectify_data__(value) : value
170
-
171
- obj.send :"#{key}=", val
172
- end # each
173
-
174
- obj
175
- end # method __objectify_data__
176
-
177
- def __set_value__ name, value, options
178
- writer_name = :"#{name}="
179
-
180
- __validate_value__ value, options
181
-
182
- if __data__.respond_to?(writer_name)
183
- __data__.send(writer_name, value)
184
- else
185
- # Store values locally if data source is immutable.
186
- instance_variable_set(:"@#{name}", value)
187
- end # if-else
188
- end # method __set_value__
189
-
190
- def __validate_value__ value, options
191
- return if __blank_value__(value) && options[:allow_nil]
192
-
193
- if options[:enum] && !options[:enum].include?(value)
194
- array_tools = ::SleepingKingStudios::Tools::ArrayTools
195
- valid_options =
196
- array_tools.
197
- humanize_list(
198
- options[:enum].map(&:inspect),
199
- :last_separator => ' or '
200
- ) # end humanize_list
201
-
202
- raise RuntimeError,
203
- "expected option to be #{valid_options}, but was #{value.inspect}"
204
- end # if
205
- end # method __validate_value__
206
- end # class
207
- end # module
@@ -1,175 +0,0 @@
1
- # lib/sleeping_king_studios/tools/toolbox/delegator.rb
2
-
3
- require 'sleeping_king_studios/tools/toolbox'
4
-
5
- module SleepingKingStudios::Tools::Toolbox
6
- # Module for extending classes with basic delegation. Supports passing
7
- # arguments, keywords, and blocks to the delegated method.
8
- #
9
- # @example
10
- # class MyClass
11
- # extend SleepingKingStudios::Tools::Delegator
12
- #
13
- # delegate :my_method, :to => MyService
14
- # end # class
15
- module Delegator
16
- # Defines a wrapper method to delegate implementation of the specified
17
- # method or methods to an object, to the object at another specified method,
18
- # or to the object at a specified instance variable.
19
- #
20
- # @example Delegate to an object
21
- # class MyModule
22
- # extend SleepingKingStudios::Tools::Toolbox::Delegator
23
- #
24
- # delegate :my_method, :to => MyService
25
- # end # class
26
- #
27
- # @example Delegate to a method
28
- # class MyModule
29
- # extend SleepingKingStudios::Tools::Toolbox::Delegator
30
- #
31
- # def my_service
32
- # MyService.new
33
- # end # method my_service
34
- #
35
- # delegate :my_method, :to => :my_service
36
- # end # class
37
- #
38
- # @example Delegate to an instance variable
39
- # class MyModule
40
- # extend SleepingKingStudios::Tools::Toolbox::Delegator
41
- #
42
- # def initialize
43
- # @my_service = MyService.new
44
- # end # constructor
45
- #
46
- # delegate :my_method, :to => :@my_service
47
- # end # class
48
- #
49
- # @param method_names [Array<String, Symbol>] The names of the methods to
50
- # delegate.
51
- # @param to [Object, String, Symbol] The object, method, or instance
52
- # variable to delegate to. If the object is not a string or symbol, the
53
- # generated method will call `method_name` on the object. If the object is
54
- # a string or symbol, but does not start with an `@`, the generated method
55
- # will call the method of that name on the instance, and then call
56
- # `method_name` on the result. If the object is a string or symbol and
57
- # does start with an `@`, the generated method will get the instance
58
- # variable of that name and call `method_name` on the result.
59
- #
60
- # @raise ArgumentError if no delegate is specified.
61
- def delegate *method_names, to: nil, allow_nil: false
62
- raise ArgumentError.new('must specify a delegate') if to.nil? && !allow_nil
63
-
64
- method_names.each do |method_name|
65
- delegate_method method_name, to, { :allow_nil => !!allow_nil }
66
- end # each
67
- end # method delegate
68
-
69
- # Wraps a delegate object by automatically delegating each method that is
70
- # defined on the delegate class from the instance to the delegate. The
71
- # delegate can be specified with an object literal or with the name of an
72
- # instance method or instance variable.
73
- #
74
- # Only methods that are defined at the time #wrap_delegate is called will be
75
- # delegated, so make sure to call #wrap_delegate after loading any gems or
76
- # libraries that extend your delegate class, such as ActiveSupport.
77
- #
78
- # @example Create a class that wraps a Hash
79
- # class Errors
80
- # extend SleepingKingStudios::Tools::Delegator
81
- #
82
- # wrap_delegate Hash.new { |hsh, key| hsh[key] = Errors.new }, :klass => Hash
83
- #
84
- # def messages
85
- # @messages ||= []
86
- # end # method messages
87
- # end # class
88
- #
89
- # errors = Errors.new
90
- # errors[:post].messages << "title can't be blank"
91
- #
92
- # @param target [Object, String, Symbol] The object, method, or instance
93
- # variable to delegate to. If the object is not a string or symbol, the
94
- # generated method will call each method on the object. If the object is
95
- # a string or symbol, but does not start with an `@`, the generated method
96
- # will call the method of that name on the instance, and then call
97
- # each method on the result. If the object is a string or symbol and
98
- # does start with an `@`, the generated method will get the instance
99
- # variable of that name and call each method on the result.
100
- # @param klass [Module] The class or module whose methods are delegated to
101
- # the target. If target is the name of an instance variable or an instance
102
- # method, the klass must be specified. If target is an object literal, the
103
- # klass is optional, in which case all methods from the target will be
104
- # delegated to the target.
105
- # @param except [Array<String, Symbol>] An optional list of method names.
106
- # Any names on the list will not be delegated, even if the method is
107
- # defined by the klass or defined on the target literal.
108
- # @param only [Array<String, Symbol>] An optional list of method names.
109
- # Only names on the list will be delegated, and only if the method is
110
- # defined by the klass or defined on the target literal.
111
- #
112
- # @raise ArgumentError if no delegate is specified.
113
- # @raise ArgumentError if the target is the name of an instance method or an
114
- # instance variable and no klass is specified.
115
- # @raise ArgumentError if the target is an object literal that does not
116
- # belong to the specified klass.
117
- #
118
- # @see #delegate
119
- def wrap_delegate target, klass: nil, except: [], only: []
120
- if klass.is_a?(Module)
121
- unless target.is_a?(String) || target.is_a?(Symbol) || target.is_a?(klass)
122
- raise ArgumentError.new "expected delegate to be a #{klass.name}"
123
- end # unless
124
-
125
- method_names = klass.instance_methods - Object.instance_methods
126
- elsif target.is_a?(String) || target.is_a?(Symbol)
127
- raise ArgumentError.new 'must specify a delegate class'
128
- else
129
- method_names = target.methods - Object.new.methods
130
- end # if-elsif-else
131
-
132
- if except.is_a?(Array) && !except.empty?
133
- method_names = method_names - except.map(&:intern)
134
- end # if
135
-
136
- if only.is_a?(Array) && !only.empty?
137
- method_names = method_names & only.map(&:intern)
138
- end # if
139
-
140
- delegate *method_names, :to => target
141
- end # method wrap_delegate
142
-
143
- private
144
-
145
- def delegate_method method_name, target, options = {}
146
- if target.is_a?(String) || target.is_a?(Symbol)
147
- target = target.intern
148
-
149
- if target.to_s =~ /\A@/
150
- define_method method_name do |*args, &block|
151
- receiver = instance_variable_get(target)
152
-
153
- return nil if receiver.nil? && options[:allow_nil]
154
-
155
- receiver.send(method_name, *args, &block)
156
- end # define_method
157
- else
158
- define_method method_name do |*args, &block|
159
- receiver = send(target)
160
-
161
- return nil if receiver.nil? && options[:allow_nil]
162
-
163
- receiver.send(method_name, *args, &block)
164
- end # define_method
165
- end # if-else
166
- else
167
- define_method method_name do |*args, &block|
168
- return nil if target.nil? && options[:allow_nil]
169
-
170
- target.send(method_name, *args, &block)
171
- end # define_method
172
- end # if
173
- end # method delegate_method
174
- end # module
175
- end # module