bblib 0.3.0 → 0.4.1

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