bblib 0.2.2 → 0.3.0
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 +4 -4
- data/README.md +178 -20
- data/bblib.gemspec +1 -0
- data/lib/array/bbarray.rb +22 -13
- data/lib/bblib.rb +27 -17
- data/lib/bblib/version.rb +1 -1
- data/lib/file/bbfile.rb +20 -31
- data/lib/gem/bbgem.rb +28 -0
- data/lib/hash/bbhash.rb +26 -13
- data/lib/hash/hash_path.rb +214 -304
- data/lib/hash/hash_path_proc.rb +82 -82
- data/lib/hash/path_hash.rb +81 -0
- data/lib/object/attr.rb +182 -0
- data/lib/object/bbobject.rb +16 -0
- data/lib/object/hooks.rb +69 -0
- data/lib/object/lazy_class.rb +73 -0
- data/lib/opal/bbopal.rb +16 -0
- data/lib/os/bbos.rb +93 -0
- data/lib/os/bbsys.rb +238 -0
- data/lib/string/bbstring.rb +36 -6
- data/lib/string/cases.rb +1 -1
- data/lib/string/fuzzy_matcher.rb +14 -19
- data/lib/string/matching.rb +1 -1
- data/lib/string/roman.rb +5 -6
- data/lib/time/cron.rb +27 -27
- data/lib/time/task_timer.rb +34 -28
- metadata +24 -2
data/lib/hash/hash_path_proc.rb
CHANGED
@@ -1,20 +1,23 @@
|
|
1
1
|
require 'time'
|
2
2
|
|
3
3
|
class Hash
|
4
|
-
def
|
5
|
-
BBLib.hash_path_proc self, action, paths, *args
|
4
|
+
def path_proc action, paths, *args
|
5
|
+
BBLib.hash_path_proc self, action, paths, *args
|
6
6
|
end
|
7
|
+
|
8
|
+
alias_method :hash_path_proc, :path_proc
|
7
9
|
end
|
8
10
|
|
9
11
|
class Array
|
10
|
-
def hash_path_proc action, paths, *args
|
11
|
-
BBLib.hash_path_proc self, action, paths, *args
|
12
|
+
def hash_path_proc action, paths, *args
|
13
|
+
BBLib.hash_path_proc self, action, paths, *args
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
15
17
|
module BBLib
|
16
18
|
|
17
|
-
def self.hash_path_proc hash, action, paths, *args
|
19
|
+
def self.hash_path_proc hash, action, paths, *args
|
20
|
+
params = BBLib::named_args(*args)
|
18
21
|
action = HASH_PATH_PROC_TYPES.keys.find{ |k| k == action || HASH_PATH_PROC_TYPES[k][:aliases].include?(action) }
|
19
22
|
return nil unless action
|
20
23
|
paths.to_a.each do |path|
|
@@ -26,91 +29,89 @@ module BBLib
|
|
26
29
|
next
|
27
30
|
end
|
28
31
|
end
|
29
|
-
HashPath.send(action, hash, path, value, *args
|
32
|
+
HashPath.send(action, hash, path, value, *args)
|
30
33
|
end
|
31
34
|
end
|
32
35
|
return hash
|
33
36
|
end
|
34
37
|
|
35
38
|
HASH_PATH_PROC_TYPES = {
|
36
|
-
evaluate:
|
37
|
-
append:
|
38
|
-
prepend:
|
39
|
-
split:
|
40
|
-
replace:
|
41
|
-
extract:
|
42
|
-
extract_first:
|
43
|
-
extract_last:
|
44
|
-
parse_date:
|
45
|
-
parse_date_unix:
|
46
|
-
parse_duration:
|
47
|
-
parse_file_size:
|
48
|
-
to_string:
|
49
|
-
downcase:
|
50
|
-
upcase:
|
51
|
-
roman:
|
52
|
-
remove_symbols:
|
53
|
-
format_articles:
|
54
|
-
reverse:
|
55
|
-
delete:
|
56
|
-
remove:
|
57
|
-
custom:
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
# rename: { aliases: [:rename_key]},
|
71
|
-
concat: { aliases: [:join, :concat_with]},
|
72
|
-
reverse_concat: { aliases: [:reverse_join, :reverse_concat_with]}
|
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
73
|
}
|
74
74
|
|
75
75
|
module HashPath
|
76
76
|
|
77
|
-
def self.evaluate hash, path, value, args
|
77
|
+
def self.evaluate hash, path, value, args
|
78
78
|
exp = args.to_a.first.to_s.gsub('$', value.to_s)
|
79
79
|
hash.hash_path_set path => eval(exp)
|
80
80
|
end
|
81
81
|
|
82
|
-
def self.append hash, path, value, args
|
82
|
+
def self.append hash, path, value, args
|
83
83
|
hash.hash_path_set path => "#{value}#{args}"
|
84
84
|
end
|
85
85
|
|
86
|
-
def self.prepend hash, path, value, args
|
86
|
+
def self.prepend hash, path, value, args
|
87
87
|
hash.hash_path_set path => "#{args}#{value}"
|
88
88
|
end
|
89
89
|
|
90
|
-
def self.split hash, path, value, args
|
90
|
+
def self.split hash, path, value, args
|
91
91
|
hash.hash_path_set path => value.msplit(args)
|
92
92
|
end
|
93
93
|
|
94
|
-
def self.replace hash, path, value, args
|
94
|
+
def self.replace hash, path, value, args
|
95
95
|
value = value.dup.to_s
|
96
96
|
args.each{ |k,v| value.gsub!(k, v.to_s) }
|
97
97
|
hash.hash_path_set path => value
|
98
98
|
end
|
99
99
|
|
100
|
-
def self.extract hash, path, value, *args
|
100
|
+
def self.extract hash, path, value, *args
|
101
101
|
slice = (Array === args && args[1].nil? ? (0..-1) : args[1])
|
102
102
|
hash.hash_path_set path => value.to_s.scan(args.first)[slice]
|
103
103
|
end
|
104
104
|
|
105
|
-
def self.extract_first hash, path, value, *args
|
105
|
+
def self.extract_first hash, path, value, *args
|
106
106
|
extract(hash, path, value, *args + [0])
|
107
107
|
end
|
108
108
|
|
109
|
-
def self.extract_last hash, path, value, *args
|
109
|
+
def self.extract_last hash, path, value, *args
|
110
110
|
extract(hash, path, value, *args + [-1])
|
111
111
|
end
|
112
112
|
|
113
|
-
def self.parse_date hash, path, value, *args
|
113
|
+
def self.parse_date hash, path, value, *args
|
114
|
+
params = BBLib::named_args(args)
|
114
115
|
format = params.include?(:format) ? params[:format] : '%Y-%m-%d %H:%M:%S'
|
115
116
|
formatted = nil
|
116
117
|
args.each do |pattern|
|
@@ -127,7 +128,8 @@ module BBLib
|
|
127
128
|
hash.hash_path_set path => formatted
|
128
129
|
end
|
129
130
|
|
130
|
-
def self.parse_date_unix hash, path, value, *args
|
131
|
+
def self.parse_date_unix hash, path, value, *args
|
132
|
+
params = BBLib::named_args(args)
|
131
133
|
format = params.include?(:format) ? params[:format] : '%Y-%m-%d %H:%M:%S'
|
132
134
|
formatted = nil
|
133
135
|
args.each do |pattern|
|
@@ -144,110 +146,108 @@ module BBLib
|
|
144
146
|
hash.hash_path_set path => formatted.to_f
|
145
147
|
end
|
146
148
|
|
147
|
-
def self.parse_duration hash, path, value, args
|
149
|
+
def self.parse_duration hash, path, value, args
|
148
150
|
hash.hash_path_set path => value.to_s.parse_duration(output: args.empty? ? :sec : args )
|
149
151
|
end
|
150
152
|
|
151
|
-
def self.parse_file_size hash, path, value, args
|
153
|
+
def self.parse_file_size hash, path, value, args
|
152
154
|
hash.hash_path_set path => value.to_s.parse_file_size(output: args.empty? ? :bytes : args )
|
153
155
|
end
|
154
156
|
|
155
|
-
def self.to_string hash, path, value, *args
|
157
|
+
def self.to_string hash, path, value, *args
|
156
158
|
hash.hash_path_set path => value.to_s
|
157
159
|
end
|
158
160
|
|
159
|
-
def self.downcase hash, path, value, *args
|
161
|
+
def self.downcase hash, path, value, *args
|
160
162
|
hash.hash_path_set path => value.to_s.downcase
|
161
163
|
end
|
162
164
|
|
163
|
-
def self.upcase hash, path, value, *args
|
165
|
+
def self.upcase hash, path, value, *args
|
164
166
|
hash.hash_path_set path => value.to_s.upcase
|
165
167
|
end
|
166
168
|
|
167
|
-
def self.roman hash, path, value, *args
|
169
|
+
def self.roman hash, path, value, *args
|
168
170
|
hash.hash_path_set path => (args[0] == :to ? value.to_s.to_roman : value.to_s.from_roman)
|
169
171
|
end
|
170
172
|
|
171
|
-
def self.remove_symbols hash, path, value, *args
|
173
|
+
def self.remove_symbols hash, path, value, *args
|
172
174
|
hash.hash_path_set path => value.to_s.drop_symbols
|
173
175
|
end
|
174
176
|
|
175
|
-
def self.format_articles hash, path, value, args
|
177
|
+
def self.format_articles hash, path, value, args
|
176
178
|
hash.hash_path_set path => value.to_s.move_articles(args.nil? ? :front : args)
|
177
179
|
end
|
178
180
|
|
179
|
-
def self.reverse hash, path, value, *args
|
181
|
+
def self.reverse hash, path, value, *args
|
180
182
|
hash.hash_path_set path => value.to_s.reverse
|
181
183
|
end
|
182
184
|
|
183
|
-
def self.delete hash, path, value, *args
|
185
|
+
def self.delete hash, path, value, *args
|
184
186
|
hash.hash_path_delete path
|
185
187
|
end
|
186
188
|
|
187
|
-
def self.remove hash, path, value, *args
|
189
|
+
def self.remove hash, path, value, *args
|
188
190
|
removed = value.to_s
|
189
191
|
args.each{ |a| removed.gsub!(a, '')}
|
190
192
|
hash.hash_path_set path => removed
|
191
193
|
end
|
192
194
|
|
193
|
-
def self.custom hash, path, value, *args
|
194
|
-
|
195
|
-
hash.hash_path_set path => value.send(*args)
|
196
|
-
else
|
197
|
-
hash.hash_path_set path => value.send(*args, **params)
|
198
|
-
end
|
195
|
+
def self.custom hash, path, value, *args
|
196
|
+
hash.hash_path_set path => value.send(*args)
|
199
197
|
end
|
200
198
|
|
201
|
-
def self.encapsulate hash, path, value, args
|
199
|
+
def self.encapsulate hash, path, value, args
|
202
200
|
hash.hash_path_set path => "#{args}#{value}#{args}"
|
203
201
|
end
|
204
202
|
|
205
|
-
def self.uncapsulate hash, path, value, args
|
203
|
+
def self.uncapsulate hash, path, value, args
|
206
204
|
value = value[args.size..-1] if value.start_with?(args)
|
207
205
|
value = value[0..-(args.size)-1] if value.end_with?(args)
|
208
206
|
hash.hash_path_set path => value
|
209
207
|
end
|
210
208
|
|
211
|
-
def self.max_number hash, path, value, *args
|
209
|
+
def self.max_number hash, path, value, *args
|
212
210
|
hash.hash_path_set path => value.to_s.extract_numbers.max
|
213
211
|
end
|
214
212
|
|
215
|
-
def self.min_number hash, path, value, *args
|
213
|
+
def self.min_number hash, path, value, *args
|
216
214
|
hash.hash_path_set path => value.to_s.extract_numbers.min
|
217
215
|
end
|
218
216
|
|
219
|
-
def self.avg_number hash, path, value, *args
|
217
|
+
def self.avg_number hash, path, value, *args
|
220
218
|
nums = value.to_s.extract_numbers
|
221
219
|
avg = nums.inject{ |s, x| s + x }.to_f / nums.size.to_f
|
222
220
|
hash.hash_path_set path => avg
|
223
221
|
end
|
224
222
|
|
225
|
-
def self.sum_number hash, path, value, *args
|
223
|
+
def self.sum_number hash, path, value, *args
|
226
224
|
hash.hash_path_set path => value.to_s.extract_numbers.inject{ |s,x| s + x }
|
227
225
|
end
|
228
226
|
|
229
|
-
def self.strip hash, path, value, args
|
227
|
+
def self.strip hash, path, value, args
|
230
228
|
value.map!{ |m| m.respond_to?(:strip) ? m.strip : m } if value.is_a?(Array)
|
231
229
|
hash.hash_path_set path => (value.respond_to?(:strip) ? value.strip : value)
|
232
230
|
end
|
233
231
|
|
234
|
-
def self.extract_integers hash, path, value, args
|
232
|
+
def self.extract_integers hash, path, value, args
|
235
233
|
hash.hash_path_set path => (value.extract_integers)
|
236
234
|
end
|
237
235
|
|
238
|
-
def self.extract_floats hash, path, value, args
|
236
|
+
def self.extract_floats hash, path, value, args
|
239
237
|
hash.hash_path_set path => (value.extract_floats)
|
240
238
|
end
|
241
239
|
|
242
|
-
def self.extract_numbers hash, path, value, args
|
240
|
+
def self.extract_numbers hash, path, value, args
|
243
241
|
hash.hash_path_set path => (value.extract_numbers)
|
244
242
|
end
|
245
243
|
|
246
|
-
def self.concat hash, path, value, *args
|
244
|
+
def self.concat hash, path, value, *args
|
245
|
+
params = BBLib::named_args(args)
|
247
246
|
hash.hash_path_set path => "#{value}#{params[:join]}#{hash.hash_path(args.first)[params[:range].nil? ? 0 : params[:range]]}"
|
248
247
|
end
|
249
248
|
|
250
|
-
def self.reverse_concat hash, path, value, *args
|
249
|
+
def self.reverse_concat hash, path, value, *args
|
250
|
+
params = BBLib::named_args(args)
|
251
251
|
hash.hash_path_set path => "#{hash.hash_path(args.first)[params[:range].nil? ? 0 : params[:range]]}#{params[:join]}#{value}"
|
252
252
|
end
|
253
253
|
|
@@ -0,0 +1,81 @@
|
|
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
|
data/lib/object/attr.rb
ADDED
@@ -0,0 +1,182 @@
|
|
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
|