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.
- checksums.yaml +5 -5
- data/.gitignore +11 -10
- data/.rspec +2 -2
- data/.travis.yml +4 -4
- data/CODE_OF_CONDUCT.md +13 -13
- data/Gemfile +4 -4
- data/LICENSE.txt +21 -21
- data/README.md +247 -757
- data/Rakefile +6 -6
- data/bblib.gemspec +34 -34
- data/bin/console +14 -14
- data/bin/setup +7 -7
- data/lib/array/bbarray.rb +71 -29
- data/lib/bblib.rb +12 -12
- data/lib/bblib/version.rb +3 -3
- data/lib/class/effortless.rb +23 -0
- data/lib/error/abstract.rb +3 -0
- data/lib/file/bbfile.rb +93 -52
- data/lib/hash/bbhash.rb +130 -46
- data/lib/hash/hash_struct.rb +24 -0
- data/lib/hash/tree_hash.rb +364 -0
- data/lib/hash_path/hash_path.rb +210 -0
- data/lib/hash_path/part.rb +83 -0
- data/lib/hash_path/path_hash.rb +84 -0
- data/lib/hash_path/proc.rb +93 -0
- data/lib/hash_path/processors.rb +239 -0
- data/lib/html/bbhtml.rb +2 -0
- data/lib/html/builder.rb +34 -0
- data/lib/html/tag.rb +49 -0
- data/lib/logging/bblogging.rb +42 -0
- data/lib/mixins/attrs.rb +422 -0
- data/lib/mixins/bbmixins.rb +7 -0
- data/lib/mixins/bridge.rb +17 -0
- data/lib/mixins/family_tree.rb +41 -0
- data/lib/mixins/hooks.rb +139 -0
- data/lib/mixins/logger.rb +31 -0
- data/lib/mixins/serializer.rb +71 -0
- data/lib/mixins/simple_init.rb +160 -0
- data/lib/number/bbnumber.rb +15 -7
- data/lib/object/bbobject.rb +46 -19
- data/lib/opal/bbopal.rb +0 -4
- data/lib/os/bbos.rb +24 -16
- data/lib/os/bbsys.rb +60 -43
- data/lib/string/bbstring.rb +165 -66
- data/lib/string/cases.rb +37 -29
- data/lib/string/fuzzy_matcher.rb +48 -50
- data/lib/string/matching.rb +43 -30
- data/lib/string/pluralization.rb +156 -0
- data/lib/string/regexp.rb +45 -0
- data/lib/string/roman.rb +17 -30
- data/lib/system/bbsystem.rb +42 -0
- data/lib/time/bbtime.rb +79 -58
- data/lib/time/cron.rb +174 -132
- data/lib/time/task_timer.rb +86 -70
- metadata +27 -10
- data/lib/gem/bbgem.rb +0 -28
- data/lib/hash/hash_path.rb +0 -344
- data/lib/hash/hash_path_proc.rb +0 -256
- data/lib/hash/path_hash.rb +0 -81
- data/lib/object/attr.rb +0 -182
- data/lib/object/hooks.rb +0 -69
- data/lib/object/lazy_class.rb +0 -73
data/lib/hash/hash_path_proc.rb
DELETED
@@ -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
|
data/lib/hash/path_hash.rb
DELETED
@@ -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
|
data/lib/object/attr.rb
DELETED
@@ -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
|