bblib 0.3.0 → 0.4.1

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.
Files changed (62) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +11 -10
  3. data/.rspec +2 -2
  4. data/.travis.yml +4 -4
  5. data/CODE_OF_CONDUCT.md +13 -13
  6. data/Gemfile +4 -4
  7. data/LICENSE.txt +21 -21
  8. data/README.md +247 -757
  9. data/Rakefile +6 -6
  10. data/bblib.gemspec +34 -34
  11. data/bin/console +14 -14
  12. data/bin/setup +7 -7
  13. data/lib/array/bbarray.rb +71 -29
  14. data/lib/bblib.rb +12 -12
  15. data/lib/bblib/version.rb +3 -3
  16. data/lib/class/effortless.rb +23 -0
  17. data/lib/error/abstract.rb +3 -0
  18. data/lib/file/bbfile.rb +93 -52
  19. data/lib/hash/bbhash.rb +130 -46
  20. data/lib/hash/hash_struct.rb +24 -0
  21. data/lib/hash/tree_hash.rb +364 -0
  22. data/lib/hash_path/hash_path.rb +210 -0
  23. data/lib/hash_path/part.rb +83 -0
  24. data/lib/hash_path/path_hash.rb +84 -0
  25. data/lib/hash_path/proc.rb +93 -0
  26. data/lib/hash_path/processors.rb +239 -0
  27. data/lib/html/bbhtml.rb +2 -0
  28. data/lib/html/builder.rb +34 -0
  29. data/lib/html/tag.rb +49 -0
  30. data/lib/logging/bblogging.rb +42 -0
  31. data/lib/mixins/attrs.rb +422 -0
  32. data/lib/mixins/bbmixins.rb +7 -0
  33. data/lib/mixins/bridge.rb +17 -0
  34. data/lib/mixins/family_tree.rb +41 -0
  35. data/lib/mixins/hooks.rb +139 -0
  36. data/lib/mixins/logger.rb +31 -0
  37. data/lib/mixins/serializer.rb +71 -0
  38. data/lib/mixins/simple_init.rb +160 -0
  39. data/lib/number/bbnumber.rb +15 -7
  40. data/lib/object/bbobject.rb +46 -19
  41. data/lib/opal/bbopal.rb +0 -4
  42. data/lib/os/bbos.rb +24 -16
  43. data/lib/os/bbsys.rb +60 -43
  44. data/lib/string/bbstring.rb +165 -66
  45. data/lib/string/cases.rb +37 -29
  46. data/lib/string/fuzzy_matcher.rb +48 -50
  47. data/lib/string/matching.rb +43 -30
  48. data/lib/string/pluralization.rb +156 -0
  49. data/lib/string/regexp.rb +45 -0
  50. data/lib/string/roman.rb +17 -30
  51. data/lib/system/bbsystem.rb +42 -0
  52. data/lib/time/bbtime.rb +79 -58
  53. data/lib/time/cron.rb +174 -132
  54. data/lib/time/task_timer.rb +86 -70
  55. metadata +27 -10
  56. data/lib/gem/bbgem.rb +0 -28
  57. data/lib/hash/hash_path.rb +0 -344
  58. data/lib/hash/hash_path_proc.rb +0 -256
  59. data/lib/hash/path_hash.rb +0 -81
  60. data/lib/object/attr.rb +0 -182
  61. data/lib/object/hooks.rb +0 -69
  62. data/lib/object/lazy_class.rb +0 -73
@@ -1,256 +0,0 @@
1
- require 'time'
2
-
3
- class Hash
4
- def path_proc action, paths, *args
5
- BBLib.hash_path_proc self, action, paths, *args
6
- end
7
-
8
- alias_method :hash_path_proc, :path_proc
9
- end
10
-
11
- class Array
12
- def hash_path_proc action, paths, *args
13
- BBLib.hash_path_proc self, action, paths, *args
14
- end
15
- end
16
-
17
- module BBLib
18
-
19
- def self.hash_path_proc hash, action, paths, *args
20
- params = BBLib::named_args(*args)
21
- action = HASH_PATH_PROC_TYPES.keys.find{ |k| k == action || HASH_PATH_PROC_TYPES[k][:aliases].include?(action) }
22
- return nil unless action
23
- paths.to_a.each do |path|
24
- hash.hash_path(path).each do |value|
25
- if params.include?(:condition) && params[:condition]
26
- begin
27
- next unless eval(params[:condition].gsub('$', value.to_s))
28
- rescue StandardError, SyntaxError => e
29
- next
30
- end
31
- end
32
- HashPath.send(action, hash, path, value, *args)
33
- end
34
- end
35
- return hash
36
- end
37
-
38
- HASH_PATH_PROC_TYPES = {
39
- evaluate: { aliases: [:eval, :equation, :equate]},
40
- append: { aliases: [:suffix]},
41
- prepend: { aliases: [:prefix]},
42
- split: { aliases: [:delimit, :delim, :separate, :msplit]},
43
- replace: { aliases: [:swap]},
44
- extract: { aliases: [:grab, :scan]},
45
- extract_first: { aliases: [:grab_first, :scan_first]},
46
- extract_last: { aliases: [:grab_last, :scan_last]},
47
- parse_date: { aliases: [:date, :parse_time, :time]},
48
- parse_date_unix: { aliases: [:unix_time, :unix_date]},
49
- parse_duration: { aliases: [:duration]},
50
- parse_file_size: { aliases: [:file_size]},
51
- to_string: { aliases: [:to_s, :stringify]},
52
- downcase: { aliases: [:lower, :lowercase, :to_lower]},
53
- upcase: { aliases: [:upper, :uppercase, :to_upper]},
54
- roman: { aliases: [:convert_roman, :roman_numeral, :parse_roman]},
55
- remove_symbols: { aliases: [:chop_symbols, :drop_symbols]},
56
- format_articles: { aliases: [:articles]},
57
- reverse: { aliases: [:invert]},
58
- delete: { aliases: [:del]},
59
- remove: { aliases: [:rem]},
60
- custom: { aliases: [:send]},
61
- encapsulate: { aliases: []},
62
- uncapsulate: {aliases: []},
63
- extract_integers: { aliases: [:extract_ints]},
64
- extract_floats: { aliases: []},
65
- extract_numbers: { aliases: []},
66
- max_number: { aliases: [:max, :maximum, :maximum_number]},
67
- min_number: { aliases: [:min, :minimum, :minimum_number]},
68
- avg_number: { aliases: [:avg, :average, :average_number]},
69
- sum_number: { aliases: [:sum]},
70
- strip: { aliases: [:trim]},
71
- concat: { aliases: [:join, :concat_with]},
72
- reverse_concat: { aliases: [:reverse_join, :reverse_concat_with]}
73
- }
74
-
75
- module HashPath
76
-
77
- def self.evaluate hash, path, value, args
78
- exp = args.to_a.first.to_s.gsub('$', value.to_s)
79
- hash.hash_path_set path => eval(exp)
80
- end
81
-
82
- def self.append hash, path, value, args
83
- hash.hash_path_set path => "#{value}#{args}"
84
- end
85
-
86
- def self.prepend hash, path, value, args
87
- hash.hash_path_set path => "#{args}#{value}"
88
- end
89
-
90
- def self.split hash, path, value, args
91
- hash.hash_path_set path => value.msplit(args)
92
- end
93
-
94
- def self.replace hash, path, value, args
95
- value = value.dup.to_s
96
- args.each{ |k,v| value.gsub!(k, v.to_s) }
97
- hash.hash_path_set path => value
98
- end
99
-
100
- def self.extract hash, path, value, *args
101
- slice = (Array === args && args[1].nil? ? (0..-1) : args[1])
102
- hash.hash_path_set path => value.to_s.scan(args.first)[slice]
103
- end
104
-
105
- def self.extract_first hash, path, value, *args
106
- extract(hash, path, value, *args + [0])
107
- end
108
-
109
- def self.extract_last hash, path, value, *args
110
- extract(hash, path, value, *args + [-1])
111
- end
112
-
113
- def self.parse_date hash, path, value, *args
114
- params = BBLib::named_args(args)
115
- format = params.include?(:format) ? params[:format] : '%Y-%m-%d %H:%M:%S'
116
- formatted = nil
117
- args.each do |pattern|
118
- next unless formatted.nil?
119
- begin
120
- formatted = Time.strptime(value.to_s, pattern.to_s).strftime(format)
121
- rescue
122
- end
123
- end
124
- begin
125
- if formatted.nil? then formatted = Time.parse(value) end
126
- rescue
127
- end
128
- hash.hash_path_set path => formatted
129
- end
130
-
131
- def self.parse_date_unix hash, path, value, *args
132
- params = BBLib::named_args(args)
133
- format = params.include?(:format) ? params[:format] : '%Y-%m-%d %H:%M:%S'
134
- formatted = nil
135
- args.each do |pattern|
136
- next unless formatted.nil?
137
- begin
138
- formatted = Time.strptime(value.to_s, pattern.to_s).strftime(format)
139
- rescue
140
- end
141
- end
142
- begin
143
- if formatted.nil? then formatted = Time.parse(value) end
144
- rescue
145
- end
146
- hash.hash_path_set path => formatted.to_f
147
- end
148
-
149
- def self.parse_duration hash, path, value, args
150
- hash.hash_path_set path => value.to_s.parse_duration(output: args.empty? ? :sec : args )
151
- end
152
-
153
- def self.parse_file_size hash, path, value, args
154
- hash.hash_path_set path => value.to_s.parse_file_size(output: args.empty? ? :bytes : args )
155
- end
156
-
157
- def self.to_string hash, path, value, *args
158
- hash.hash_path_set path => value.to_s
159
- end
160
-
161
- def self.downcase hash, path, value, *args
162
- hash.hash_path_set path => value.to_s.downcase
163
- end
164
-
165
- def self.upcase hash, path, value, *args
166
- hash.hash_path_set path => value.to_s.upcase
167
- end
168
-
169
- def self.roman hash, path, value, *args
170
- hash.hash_path_set path => (args[0] == :to ? value.to_s.to_roman : value.to_s.from_roman)
171
- end
172
-
173
- def self.remove_symbols hash, path, value, *args
174
- hash.hash_path_set path => value.to_s.drop_symbols
175
- end
176
-
177
- def self.format_articles hash, path, value, args
178
- hash.hash_path_set path => value.to_s.move_articles(args.nil? ? :front : args)
179
- end
180
-
181
- def self.reverse hash, path, value, *args
182
- hash.hash_path_set path => value.to_s.reverse
183
- end
184
-
185
- def self.delete hash, path, value, *args
186
- hash.hash_path_delete path
187
- end
188
-
189
- def self.remove hash, path, value, *args
190
- removed = value.to_s
191
- args.each{ |a| removed.gsub!(a, '')}
192
- hash.hash_path_set path => removed
193
- end
194
-
195
- def self.custom hash, path, value, *args
196
- hash.hash_path_set path => value.send(*args)
197
- end
198
-
199
- def self.encapsulate hash, path, value, args
200
- hash.hash_path_set path => "#{args}#{value}#{args}"
201
- end
202
-
203
- def self.uncapsulate hash, path, value, args
204
- value = value[args.size..-1] if value.start_with?(args)
205
- value = value[0..-(args.size)-1] if value.end_with?(args)
206
- hash.hash_path_set path => value
207
- end
208
-
209
- def self.max_number hash, path, value, *args
210
- hash.hash_path_set path => value.to_s.extract_numbers.max
211
- end
212
-
213
- def self.min_number hash, path, value, *args
214
- hash.hash_path_set path => value.to_s.extract_numbers.min
215
- end
216
-
217
- def self.avg_number hash, path, value, *args
218
- nums = value.to_s.extract_numbers
219
- avg = nums.inject{ |s, x| s + x }.to_f / nums.size.to_f
220
- hash.hash_path_set path => avg
221
- end
222
-
223
- def self.sum_number hash, path, value, *args
224
- hash.hash_path_set path => value.to_s.extract_numbers.inject{ |s,x| s + x }
225
- end
226
-
227
- def self.strip hash, path, value, args
228
- value.map!{ |m| m.respond_to?(:strip) ? m.strip : m } if value.is_a?(Array)
229
- hash.hash_path_set path => (value.respond_to?(:strip) ? value.strip : value)
230
- end
231
-
232
- def self.extract_integers hash, path, value, args
233
- hash.hash_path_set path => (value.extract_integers)
234
- end
235
-
236
- def self.extract_floats hash, path, value, args
237
- hash.hash_path_set path => (value.extract_floats)
238
- end
239
-
240
- def self.extract_numbers hash, path, value, args
241
- hash.hash_path_set path => (value.extract_numbers)
242
- end
243
-
244
- def self.concat hash, path, value, *args
245
- params = BBLib::named_args(args)
246
- hash.hash_path_set path => "#{value}#{params[:join]}#{hash.hash_path(args.first)[params[:range].nil? ? 0 : params[:range]]}"
247
- end
248
-
249
- def self.reverse_concat hash, path, value, *args
250
- params = BBLib::named_args(args)
251
- hash.hash_path_set path => "#{hash.hash_path(args.first)[params[:range].nil? ? 0 : params[:range]]}#{params[:join]}#{value}"
252
- end
253
-
254
- end
255
-
256
- end
@@ -1,81 +0,0 @@
1
-
2
- # This module provides similar functionality as hash path, but instead
3
- # generates a PathHash object which wraps a Hash or Array. Elements may
4
- # be accessed via method calls rather than path strings.
5
-
6
- module BBLib
7
-
8
- def self.path_hash hash
9
- PathHash.new(hash)
10
- end
11
-
12
- class PathHash < BasicObject
13
- attr_reader :hash, :recursive
14
-
15
- def initialize hash
16
- @hash = hash
17
- end
18
-
19
- def [] val
20
- PathHash.new(@hash.map{ |h| h[val]} )
21
- end
22
-
23
- def _val
24
- @hash
25
- end
26
-
27
- alias_method :_v, :_val
28
-
29
- def _fval
30
- @hash.first rescue @hash
31
- end
32
-
33
- alias_method :_f, :_fval
34
-
35
- def _
36
- @recursive = true
37
- self
38
- end
39
-
40
- def _path arg, formula = nil
41
- method_missing arg, formula
42
- end
43
-
44
- private
45
-
46
- def method_missing arg, formula = nil
47
- arg = (@recursive ? "..#{arg}" : arg.to_s) +
48
- (formula ? "(#{formula})" : '')
49
- if @hash.is_a?(::Array)
50
- PathHash.new @hash.map{ |h| if h.is_a?(::Array) || h.is_a?(::Hash) then h.hash_path(arg) end }.flatten(1)
51
- else
52
- PathHash.new @hash.hpath(arg)
53
- end
54
- end
55
-
56
- end
57
-
58
- end
59
-
60
-
61
- class Hash
62
-
63
- def path_hash
64
- BBLib::path_hash(self)
65
- end
66
-
67
- alias_method :phash, :path_hash
68
- alias_method :_ph, :path_hash
69
-
70
- end
71
-
72
- class Array
73
-
74
- def path_hash
75
- BBLib::path_hash(self)
76
- end
77
-
78
- alias_method :phash, :path_hash
79
- alias_method :_ph, :path_hash
80
-
81
- end
@@ -1,182 +0,0 @@
1
- module BBLib::Attr
2
-
3
- private
4
-
5
- def attr_type method, opts, &block
6
- define_method("#{method}=", &block)
7
- define_method(method){ instance_variable_get("@#{method}")}
8
- if defined?(:before) && opts.include?(:default)
9
- define_method("__reset_#{method}".to_sym){ send("#{method}=", opts[:default]) }
10
- end
11
- end
12
-
13
- def attr_sender call, *methods, **opts
14
- methods.each do |m|
15
- attr_type(
16
- m,
17
- opts,
18
- &attr_set(
19
- m,
20
- opts.merge(sender: true)
21
- ){ |x| x.nil? && opts[:allow_nil] ? nil : x.send(call) }
22
- )
23
- end
24
- end
25
-
26
- def attr_of klass, *methods, **opts
27
- methods.each{ |m| attr_type(m, opts, &attr_set(m, opts){ |x|
28
- if x.is_a?(klass)
29
- instance_variable_set("@#{m}", x)
30
- else
31
- raise ArgumentError, "#{method} must be set to a #{klass}!"
32
- end
33
- }
34
- )
35
- }
36
- end
37
-
38
- def attr_boolean *methods, **opts
39
- methods.each{ |m|
40
- attr_type(m, opts) { |x| instance_variable_set("@#{m}", !!x && x.to_s != 'false') }
41
- alias_method "#{m}?", m unless opts[:no_q]
42
- }
43
- end
44
-
45
- alias_method :attr_bool, :attr_boolean
46
-
47
- def attr_string *methods, **opts
48
- attr_sender :to_s, *methods, opts
49
- end
50
-
51
- alias_method :attr_str, :attr_string
52
- alias_method :attr_s, :attr_string
53
-
54
- def attr_integer *methods, **opts
55
- attr_sender :to_i, *methods, opts
56
- end
57
-
58
- alias_method :attr_int, :attr_integer
59
- alias_method :attr_i, :attr_integer
60
-
61
- def attr_float *methods, **opts
62
- attr_sender :to_f, *methods, opts
63
- end
64
-
65
- alias_method :attr_f, :attr_float
66
-
67
- def attr_integer_between min, max, *methods, **opts
68
- methods.each{ |m| attr_type(m, opts, &attr_set(m, opts){ |x| BBLib::keep_between(x, min, max) })}
69
- end
70
-
71
- alias_method :attr_int_between, :attr_integer_between
72
- alias_method :attr_i_between, :attr_integer_between
73
- alias_method :attr_float_between, :attr_integer_between
74
- alias_method :attr_f_between, :attr_float_between
75
-
76
- def attr_symbol *methods, **opts
77
- methods.each{ |m| attr_type(m, opts, &attr_set(m, opts){ |x| x.to_s.to_sym } )}
78
- end
79
-
80
- alias_method :attr_sym, :attr_symbol
81
-
82
- def attr_clean_symbol *methods, **opts
83
- methods.each{ |m| attr_type(m, opts, &attr_set(m, opts){ |x| x.to_s.to_clean_sym } )}
84
- end
85
-
86
- alias_method :attr_clean_sym, :attr_clean_symbol
87
-
88
- def attr_array *methods, **opts
89
- methods.each{ |m| attr_type(m, opts, &attr_set(m, opts){ |*x| instance_variable_set("@#{m}", x) } )}
90
- end
91
-
92
- alias_method :attr_ary, :attr_array
93
-
94
- def attr_element_of list, *methods, **opts
95
- methods.each do |m|
96
- attr_type(m, opts, &attr_set(m, opts) do |x|
97
- if !list.include?(x)
98
- raise ArgumentError, "#{m} only accepts the following (first 10 shown) #{list[0...10]}"
99
- else
100
- instance_variable_set("@#{m}", x)
101
- end
102
- end
103
- )
104
- end
105
- end
106
-
107
- def attr_array_of klass, *methods, raise: false, **opts
108
- methods.each do |m|
109
- attr_type(m, opts, &attr_set(m, opts) do |*x|
110
- if raise && x.any?{ |i| klass.is_a?(Array) ? !klass.any?{ |k| i.is_a?(k) } : !i.is_a?(klass) }
111
- raise ArgumentError, "#{m} only accepts items of class #{klass}."
112
- end
113
- instance_variable_set("@#{m}", x.reject{|i| klass.is_a?(Array) ? !klass.any?{ |k| i.is_a?(k) } : !i.is_a?(klass) })
114
- end
115
- )
116
- end
117
- end
118
-
119
- alias_method :attr_ary_of, :attr_array_of
120
-
121
- def attr_hash *methods, **opts
122
- methods.each{ |m| attr_type(m, opts, &attr_set(m, opts) do |*a|
123
- begin
124
- hash = a.find_all{ |i| i.is_a?(Hash) }.inject({}){ |m, h| m.merge(h) } || Hash.new
125
- instance_variable_set("@#{m}", hash)
126
- rescue ArgumentError => e
127
- raise ArgumentError, "#{m} only accepts a hash for its parameters"
128
- end
129
- end
130
- )
131
- }
132
- end
133
-
134
- def attr_valid_file *methods, raise: true, **opts
135
- methods.each{ |m| attr_type(m, opts, &attr_set(m, opts){ |x| File.exists?(x.to_s) ? x.to_s : (raise ? raise(ArgumentError, "File '#{x}' does not exist. @#{m} must be set to a valid file location!") : nil)} )}
136
- end
137
-
138
- def attr_valid_dir *methods, raise: true, **opts
139
- methods.each{ |m| attr_type(m, opts, &attr_set(m, opts){ |x| Dir.exists?(x.to_s) ? x.to_s : (raise ? raise(ArgumentError, "Dir '#{x}' does not exist. @#{m} must be set to a valid directory location!") : nil)} )}
140
- end
141
-
142
- def attr_time *methods, **opts
143
- methods.each do |m|
144
- attr_type(
145
- m,
146
- opts,
147
- &attr_set(m, opts){ |x|
148
- if x.is_a?(Time) || x.nil? && opt[:allow_nil]
149
- x
150
- elsif x.is_a?(Numeric)
151
- Time.at(x)
152
- elsif x.is_a?(String)
153
- Time.parse(x)
154
- else
155
- raise "#{x} is an invalid Time object and could not be converted into a Time object."
156
- end
157
- }
158
- )
159
- end
160
- end
161
-
162
- def attr_set method, allow_nil: false, fallback: :_nil, sender: false, default: nil, &block
163
- proc{ |x|
164
- if x.nil? && !allow_nil && fallback == :_nil && !sender
165
- raise ArgumentError, "#{method} cannot be set to nil!"
166
- elsif x.nil? && !allow_nil && fallback != :_nil && !sender
167
- instance_variable_set("@#{method}", fallback)
168
- else
169
- begin
170
- instance_variable_set("@#{method}", x.nil? && !sender ? x : yield(x) )
171
- rescue Exception => e
172
- if fallback != :_nil
173
- instance_variable_set("@#{method}", fallback)
174
- else
175
- raise e
176
- end
177
- end
178
- end
179
- }
180
- end
181
-
182
- end