bblib 1.0.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +502 -8
  3. data/lib/bblib.rb +1 -28
  4. data/lib/bblib/all.rb +5 -0
  5. data/lib/{time → bblib/classes}/cron.rb +0 -0
  6. data/lib/{string → bblib/classes}/fuzzy_matcher.rb +0 -0
  7. data/lib/bblib/cli.rb +3 -0
  8. data/lib/bblib/cli/color.rb +51 -0
  9. data/lib/bblib/cli/exceptions/invalid_argument.rb +5 -0
  10. data/lib/bblib/cli/exceptions/missing_argument.rb +5 -0
  11. data/lib/bblib/cli/exceptions/missing_required_argument.rb +5 -0
  12. data/lib/bblib/cli/exceptions/opts_parser.rb +9 -0
  13. data/lib/bblib/cli/option.rb +116 -0
  14. data/lib/bblib/cli/options/basic_option.rb +19 -0
  15. data/lib/bblib/cli/options/bool.rb +19 -0
  16. data/lib/bblib/cli/options/command.rb +11 -0
  17. data/lib/bblib/cli/options/date.rb +14 -0
  18. data/lib/bblib/cli/options/float.rb +14 -0
  19. data/lib/bblib/cli/options/integer.rb +14 -0
  20. data/lib/bblib/cli/options/json.rb +16 -0
  21. data/lib/bblib/cli/options/regexp.rb +17 -0
  22. data/lib/bblib/cli/options/string.rb +13 -0
  23. data/lib/bblib/cli/options/symbol.rb +13 -0
  24. data/lib/bblib/cli/options/time.rb +14 -0
  25. data/lib/bblib/cli/options/toggle.rb +27 -0
  26. data/lib/bblib/cli/options/untoggle.rb +18 -0
  27. data/lib/bblib/cli/opts_parser.rb +65 -0
  28. data/lib/bblib/core.rb +37 -0
  29. data/lib/{hash → bblib/core/classes}/hash_struct.rb +9 -2
  30. data/lib/bblib/core/classes/splitter.rb +101 -0
  31. data/lib/{time → bblib/core/classes}/task_timer.rb +0 -0
  32. data/lib/{hash → bblib/core/classes}/tree_hash.rb +22 -22
  33. data/lib/bblib/core/exceptions/abstract.rb +3 -0
  34. data/lib/bblib/core/exceptions/exception.rb +5 -0
  35. data/lib/{hash_path → bblib/core/hash_path}/hash_path.rb +0 -2
  36. data/lib/{hash_path → bblib/core/hash_path}/part.rb +0 -0
  37. data/lib/{mixins → bblib/core/mixins}/attrs.rb +17 -7
  38. data/lib/{mixins → bblib/core/mixins}/bbmixins.rb +1 -0
  39. data/lib/{mixins → bblib/core/mixins}/bridge.rb +0 -0
  40. data/lib/bblib/core/mixins/delegator.rb +90 -0
  41. data/lib/{class → bblib/core/mixins}/effortless.rb +0 -0
  42. data/lib/{mixins → bblib/core/mixins}/family_tree.rb +1 -1
  43. data/lib/{mixins → bblib/core/mixins}/hooks.rb +0 -0
  44. data/lib/{mixins → bblib/core/mixins}/logger.rb +0 -0
  45. data/lib/{mixins → bblib/core/mixins}/prototype.rb +0 -0
  46. data/lib/{mixins → bblib/core/mixins}/serializer.rb +0 -0
  47. data/lib/{mixins → bblib/core/mixins}/simple_init.rb +41 -3
  48. data/lib/{mixins → bblib/core/mixins}/type_init.rb +0 -0
  49. data/lib/{array/bbarray.rb → bblib/core/util/array.rb} +0 -0
  50. data/lib/{string → bblib/core/util}/cases.rb +0 -0
  51. data/lib/{file/bbfile.rb → bblib/core/util/file.rb} +31 -7
  52. data/lib/{hash/bbhash.rb → bblib/core/util/hash.rb} +0 -3
  53. data/lib/{logging/bblogging.rb → bblib/core/util/logging.rb} +11 -2
  54. data/lib/{string → bblib/core/util}/matching.rb +0 -0
  55. data/lib/{number/bbnumber.rb → bblib/core/util/number.rb} +0 -0
  56. data/lib/{object/bbobject.rb → bblib/core/util/object.rb} +2 -0
  57. data/lib/{opal/bbopal.rb → bblib/core/util/opal.rb} +0 -0
  58. data/lib/{os/bbos.rb → bblib/core/util/os.rb} +0 -0
  59. data/lib/{string → bblib/core/util}/pluralization.rb +0 -0
  60. data/lib/{string → bblib/core/util}/regexp.rb +0 -0
  61. data/lib/{string → bblib/core/util}/roman.rb +0 -0
  62. data/lib/{string/bbstring.rb → bblib/core/util/string.rb} +18 -24
  63. data/lib/{time/bbtime.rb → bblib/core/util/time.rb} +1 -5
  64. data/lib/bblib/cron.rb +2 -0
  65. data/lib/bblib/fuzzy_matcher.rb +2 -0
  66. data/lib/bblib/html.rb +4 -0
  67. data/lib/{html → bblib/html}/builder.rb +0 -0
  68. data/lib/{html → bblib/html}/tag.rb +0 -0
  69. data/lib/{html → bblib/html}/tag_set.rb +0 -0
  70. data/lib/bblib/system.rb +3 -0
  71. data/lib/bblib/system/command.rb +7 -0
  72. data/lib/bblib/system/system.rb +39 -0
  73. data/lib/bblib/version.rb +1 -1
  74. metadata +71 -44
  75. data/lib/error/abstract.rb +0 -3
  76. data/lib/hash_path/path_hash.rb +0 -84
  77. data/lib/hash_path/proc.rb +0 -93
  78. data/lib/hash_path/processors.rb +0 -239
  79. data/lib/html/bbhtml.rb +0 -3
  80. data/lib/system/bbsystem.rb +0 -42
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8de738293171e9bdf15bf8b494cc55fb4353b088c01219df302b886218ad1176
4
- data.tar.gz: 5623dacf641eed1205a0c2ed76919d3e2d1c56cea40f1c7270e965104d41f25e
3
+ metadata.gz: 91fb0dde18d2401810ff65d7e22217c5495aa2e29ba29a94c6499f3caf24c15b
4
+ data.tar.gz: 4c1a1dbcbe3fe0cdd23ff487a879eae8e0156858bb2558d228e412325d2627c4
5
5
  SHA512:
6
- metadata.gz: 425b7aaa6a8d5a736ab0d89604828f9918c444b2895d7f3174939a884f7964ab6d6b510e9575d1483a5b573c8308e5921f723cb46704578df85f866da4512f88
7
- data.tar.gz: f55d3693b96705cedf0a376eb3bc7f8df1102a2f4b1efeb90f4c9832a24a5b216719122b4de4a61d412ad3ce9a76fba79c8c22c4ed11ca3f640fc3ff0a6887e2
6
+ metadata.gz: 026414e187b76e482f0eb6ae4a356850df2d5b3d124d7ec9a2d077bb259ba60facd3acfe78790d9b0949701c65fa893514f4a56bd8027401e17f5f53745b9737
7
+ data.tar.gz: 97095acae7cd31642e589892f4bf6274a476c2c69cf8b6cc9598658e306d2a772852c83eabffd8be5e6d0933b520cf41199ec95c197824ded5e77b231154ecab
data/README.md CHANGED
@@ -1,10 +1,51 @@
1
1
  # BBLib
2
2
 
3
- BBLib is a collection of various methods and classes that aim to extend the Ruby language. One of the primary goals with the BBLib is to keep it as lightweight as possible. This means you will not find dependencies outside of the Ruby core libraries.
4
-
5
- Good news! BBLib is now compatible with Opal! Well, like 90% compatible (some portions are excluded when running in Opal), but it can be 100% compiled into Javascript. Only very small tweaks were made to support this, so base functionality for the BBLib outside of Opal remains the same. But now it can coexist as both a Ruby gem, and an Opal library.
6
-
7
- BBLib contains A LOT of functionality, but is a very small, lightweight library. As such, it can be hard to document everything that is included (and even harder to make a TL:DR version). The usage section below contains most of the highlights and important features. The source code contains the rest.
3
+ BBLib is a collection of reusable methods and classes that are helpful to have in most Ruby applications or scripts. There is a lot of content here and you should be warned that BBLib does MonkeyPatch several Ruby classes (Hash, Array, String, Integer, Float). The Usage section below covers some of the highlights but for complete coverage of everything included, take a look at the YARD documentation.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Installation](#installation)
8
+ - [Usage](#usage)
9
+ - [Effortless](#effortless)
10
+ - [Attrs](#attrs)
11
+ - [Disclaimer](#disclaimer)
12
+ - [General](#general)
13
+ - [attr_string](#attr_string)
14
+ - [attr_symbol](#attr_symbol)
15
+ - [attr_integer && attr_float](#attr_integer-attr_float)
16
+ - [attr_boolean](#attr_boolean)
17
+ - [attr_integer_between && attr_float_between](#attr_integer_between-attr_float_between)
18
+ - [attr_integer_loop && attr_float_loop](#attr_integer_loop-attr_float_loop)
19
+ - [attr_array](#attr_array)
20
+ - [attr_hash](#attr_hash)
21
+ - [attr_of](#attr_of)
22
+ - [attr_array_of](#attr_array_of)
23
+ - [attr_element_of](#attr_element_of)
24
+ - [attr_elements_of](#attr_elements_of)
25
+ - [attr_file](#attr_file)
26
+ - [attr_dir](#attr_dir)
27
+ - [attr_time && attr_date](#attr_time-attr_date)
28
+ - [Simple Init](#simple-init)
29
+ - [Family Tree](#family-tree)
30
+ - [Bridge](#bridge)
31
+ - [Hooks](#hooks)
32
+ - [Serializer](#serializer)
33
+ - [Hash Path](#hash-path)
34
+ - [Path options](#path-options)
35
+ - [TreeHash](#treehash)
36
+ - [String Methods](#string-methods)
37
+ - [FuzzyMatcher](#fuzzymatcher)
38
+ - [Numeric Methods](#numeric-methods)
39
+ - [OS / System Methods](#os-system-methods)
40
+ - [Time Methods](#time-methods)
41
+ - [Hash Methods](#hash-methods)
42
+ - [Array Methods](#array-methods)
43
+ - [File Methods](#file-methods)
44
+ - [HTML Methods](#html-methods)
45
+ - [Logging](#logging)
46
+ - [Development](#development)
47
+ - [Contributing](#contributing)
48
+ - [License](#license)
8
49
 
9
50
  ## Installation
10
51
 
@@ -24,9 +65,432 @@ Or install it yourself as:
24
65
 
25
66
  ## Usage
26
67
 
68
+ ### Effortless
69
+
70
+ BBLib provides a collection of mixins meant to DRY up Ruby as much as possible. The collection of these mixins are brought together in Effortless. There are many things that classes that implement effortless can benefit from. Here is a quick breakdown of some of what it adds:
71
+
72
+ - New attr methods to store specific object types (like attr_string or attr_bool)
73
+ - Automatic creation of initialize method based on attr methods (never write an initialize again!)
74
+ - Automatic serialization (to Hash) based on attr methods (or other methods). Plus you can then instantiate Effortless classes from these serializations.
75
+ - Hooks for methods. Create simple before and after hooks to ensure certain methods are called before or after any others.
76
+ - Ability to find all subclasses of a class or all instantiations of a class.
77
+
78
+ How about an example?
79
+ ```ruby
80
+ # All we have to do is include the BBLib::Effortless module in a class
81
+ class Cat
82
+ include BBLib::Effortless
83
+
84
+ GENDER = [:unknown, :male, :female].freeze
85
+
86
+ # Now create getters/setters for our cat attributes
87
+ attr_str :name, arg_at: 0, required: true
88
+ attr_date :birthday
89
+ attr_element_of GENDER, :gender, default: :unknown
90
+ attr_int :age
91
+
92
+ # Create after hook to calculate the cat's age every time the birthday setter is called
93
+ after :birthday=, :calculate_age
94
+
95
+ def calculate_age
96
+ self.age = Time.now.year - birthday.year
97
+ end
98
+
99
+ end
100
+
101
+ # Now we can create cat objects using our attr methods
102
+ my_cat = Cat.new(name: 'Jackson', birthday: '2014-05-20', gender: :male)
103
+ puts my_cat
104
+ # => #<Cat:0x0000000005b4b310>
105
+
106
+ # Since name has the arg_at option set to element 0, we can also create a Cat like this
107
+ # (where the cat's name is the first unnamed argument)
108
+ your_cat = Cat.new('Nehra', birthday: '2017-02-14', gender: :female)
109
+ p your_cat
110
+ # => #<Cat:0x0000000005bc5ed0 @name="Nehra", @birthday=#<Date: 2017-02-14 ((2457799j,0s,0n),+0s,2299161j)>, @age=1, @gender=:female>
111
+
112
+ # We can then serialize the class into a hash
113
+ puts my_cat.serialize
114
+ # => {:name=>"Jackson", :birthday=>#<Date: 2014-05-20 ((2456798j,0s,0n),+0s,2299161j)>, :gender=>:male, :age=>4}
115
+ ```
116
+
117
+ #### Attrs
118
+
119
+ As shown in the example above, once BBLib::Effortless is included into a class a new set of attr methods become available within it to automatically build getters/setters. Here is a break down of the available attr methods, what they do and what options are available to them.
120
+
121
+ NOTE: All attr methods can take any number of method_names in one call. For example:
122
+ ```ruby
123
+ # Create a string getter and setter for first_name, last_name and address
124
+ attr_str :first_name, :last_name, :address, required: true
125
+ ```
126
+
127
+ The important thing to remember is that any arguments (such as required: in the example above) will apply to ALL of the methods on that line. So if, for example, address was not required but first_name and last_name were, the attr calls should look like this:
128
+
129
+ ```ruby
130
+ attr_str :first_name, :last_name, required: true
131
+ attr_str :address
132
+ ```
133
+
134
+ NOTE: The attr methods can be added without including all of Effortless by including only the BBLib::Attrs module.
135
+
136
+ ##### Disclaimer
137
+
138
+ When using Effortless you should no longer declare or call instance variables in your class. Effortless takes care of creating these and setting default values to them when the corresponding method name is called. Calling them or interacting with them directly also bypasses the logic Effortless applies, so don't do it!
139
+
140
+ ```ruby
141
+ class Dog
142
+ include BBLib::Effortless
143
+ attr_str :name
144
+ attr_time :birthdate, default_proc: proc { Time.now }
145
+
146
+ # FAIL, stop typing @!
147
+ # The default_proc method would normally take care of setting a default so
148
+ # that it is ensured @birthdate is a Date. In the case below, it's possible
149
+ # @birthdate is undefined and an error will be thrown.
150
+ def age
151
+ @birthdate.year - Time.now
152
+ end
153
+
154
+ # Good
155
+ # Calling the birthdate method will take care of setting the default value
156
+ # if one has not already been set. This method will always work.
157
+ def age
158
+ birthdate.year - Time.now
159
+ end
160
+
161
+ end
162
+ ```
163
+
164
+ ##### General
165
+
166
+ First, here are the global options available to all attr methods. Options are passed to the attr methods as named parameters. The object/value types in the square brackets indicate the type of value each argument expects.
167
+
168
+ - __required__: [true/false] Used by the SimpleInit module. If set to true, an exception will be raised when this class is instantiated unless this variable is passed to the constructor.
169
+ - __allow_nil__: [true/false] Most attr methods have type casting that occurs or will throw errors when being set to nil (or any unexpected object type). If you wish to allow nil to be set to your instance variable, set allow_nil to true.
170
+ - __serialize__: [true/false] When set to false this method will not be returned in the .serialize method.
171
+ - __default__: [Object] Sets the default value for this attr method if nothing is passed in.
172
+ - __default_proc__: [Proc, Symbol] A proc or symbol can be passed in. This works similarly to default but instead calls the Proc or method (Symbol) and sets the default to the result. This is useful when the default is based on an external source that is dynamic.
173
+ - __aliases__: [Array of Symbols] Creates an alias to the method for each alias passed in.
174
+ - __singleton__: [true/false] When set to true the method is placed on the singleton class as a class method rather than an instance method.
175
+ - __private__: [true/false] When set to true the getter and setter are set to private. To specifically make the getter or setter private you can instead use :private_reader or :private_writer
176
+ - __protected__: [true/false] Same as private, but the methods will be protected.
177
+ - __pre_proc__: [Proc, Symbol] When provided, the Proc or method (Symbol) will be called and passed the value being sent to the setter for pre processing. For example, this can be used to downcase a string being set in an attr_str setter.
178
+
179
+ ##### attr_string
180
+
181
+ __attr_string__ or __attr_str__ can be used to create a getter/setter pair that will store a string. Any argument being passed to the setter will have to_s called on it (unless it is nil and allow_nil is set to true).
182
+
183
+ ```ruby
184
+ # Usage: attr_str <method_name>, [options]
185
+ attr_str :first_name, default: 'Unknown'
186
+ ```
187
+ - *There are no special options for attr_string*
188
+
189
+ ##### attr_symbol
190
+
191
+ __attr_symbol__ or __attr_sym__ creates a getter and setter that will store a symbol. Any value being passed in will have to_sym called on it.
192
+
193
+ ```ruby
194
+ # Usage: attr_sym <method_name>, [options]
195
+ attr_sym :http_method, default: :get, serialize: false
196
+ ```
197
+ - *There are no special options for attr_symbol*
198
+
199
+ ##### attr_integer && attr_float
200
+
201
+ __attr_integer__ or __attr_int__ creates a getter and setter that will store an Integer. __attr_float__ is similar but stores floats. to_i and to_f will be called respectively on any value passed in to the setter.
202
+
203
+ ```ruby
204
+ # Usage: attr_int <method_name>, [options]
205
+ # attr_float <method_name>, [options]
206
+ attr_int :size, default: 0
207
+
208
+ # Below we create a percent attribute and use a pre_proc to ensure
209
+ # percentage values greater than 1 are divided by 100.
210
+ attr_float :percent, pre_proc: proc { |x| x > 1.0 ? x / 100.0 : x }
211
+ ```
212
+
213
+ - *There are no special options for attr_symbol*
214
+
215
+ ##### attr_boolean
216
+
217
+ __attr_boolean__ or __attr_bool__ creates a getter and setter that will store true of false. Values passed in to the setter are considered to be true unless they are of NilClass or FalseClass. By default, __attr_boolean__ will also create an alias for the getter with a ? at the end (see example below).
218
+
219
+ ```ruby
220
+ # Usage: attr_bool <method_name> [options]
221
+ attr_bool :active, default: false
222
+
223
+ # This creates the methods 'active' and 'active?' to return the value of the attribute.
224
+ ```
225
+
226
+ The following special options are available to attr_bool:
227
+ - __no_?__: [true/false] When set to false the question mark version of the getter will not be created. (default is true)
228
+
229
+ ##### attr_integer_between && attr_float_between
230
+ __attr_integer_between__ or __attr_int_between__ creates an integer getter and setter but ensures the value stored is between a min and max value. If the value exceeds the max it is set to max and if it is lower than min it is set to min. __attr_float_between__ is the same but stores floats between a min and max. To specify no max or no min, set min or max to nil (which means no bounds).
231
+
232
+ ```ruby
233
+ # Usage: attr_int_between <min>, <max>, <method_name> [options]
234
+ # attr_float_between <min>, <max>, <method_name> [options]
235
+ attr_int_between 0, 100, :score
236
+ attr_float_between 0, 1.0, :percent, default: 0
237
+ ```
238
+
239
+ - *There are no special options for __attr_integer_between__*
240
+
241
+ ##### attr_integer_loop && attr_float_loop
242
+
243
+ __attr_integer_loop__ is very similar to attr_integer_between with one key difference. If the max boundary is exceeded the value is instead set to the minimum. If the value is lower than min, the value is then set to max. Setting either min or max to nil would void this behavior and should not be done.
244
+
245
+ ```ruby
246
+ # Usage: attr_integer_loop <min>, <max>, <method_name>, [options]
247
+ attr_integer_loop 0, 10, :counter, default: 0
248
+ ```
249
+
250
+ - *There are no special options for __attr_integer_between__*
251
+
252
+ ##### attr_array
253
+ __attr_array__ or __attr_ary__ creates a getter and setter for an Array. The Array will allow any type of objects to be store in it. If you wish to create an Array to store specific types of Objects see the __attr_array_of__ method. Several options are available including the ability to have the __attr_array__ method automatically create adder and remover methods (to add/remove items from the array without having to use the setter).
254
+
255
+ NOTE: It is unnecessary to specify the default as [], as that is done automatically.
256
+
257
+ ```ruby
258
+ # Usage: attr_ary <method_name>, [options]
259
+ attr_ary :items, uniq: true
260
+ attr_ary :cats, add_rem: true, adder_name: :add_cat, remover_name: :remove_cat
261
+ ```
262
+
263
+ The following special options are available for attr_array:
264
+ - __uniq__: [true/false] Ensures all items inside the array are unique. (default is false)
265
+ - __add_rem__: [true/false] Automatically creates an adder and remover method. They will be named add_<method_name> and remove_<method_name> by default. Naming can be defined in the adder_name and remover_name options. (default is false)
266
+ - __adder_name__: [String, Symbol] Sets a custom name for the adder method. add_rem must be set to true for this to matter.
267
+ - __remover_name__: [String, Symbol] Sets a custom name for the remover method. add_rem must be set to true for this to matter.
268
+
269
+
270
+ ##### attr_hash
271
+
272
+ __attr_hash__ creates a getter and setter for a hash object. By default any keys and values are allowed but the types can be controlled using the *keys* and *values* options. It is unnecessary to set the default to {} as that is done automatically.
273
+
274
+ NOTE: The keys and values options only enforces the types when the hash is set via the setter. If it is interacted with directly any object types will be allowed (as is standard for Ruby Hashes).
275
+
276
+ ```ruby
277
+ # Usage: attr_hash <method_name>, [options]
278
+ attr_hash :options
279
+
280
+ # Create a hash that only allows Symbols for keys and strings or integers for values
281
+ attr_hash :attributes, keys: [Symbol], values: [String, Integer]
282
+ ```
283
+
284
+ The following options are available to attr_hash:
285
+ - __keys__: [Array of Classes] An array of classes that are allowed to be used as keys. If an invalid type is passed in an exception is raised.
286
+ - __values__: [Array of Classes] An array of classes that are allowed to be used as values. If an invalid type is passed in an exception is raised.
287
+ - __symbol_keys__: [true/false] When set to true, all keys will be converted to symbols (recursively). This is useful if you want to convert string keys to symbols (such as when the hash is being read in as JSON). (default is false)
288
+
289
+ ##### attr_of
290
+
291
+ __attr_of__ creates a getter and setter that will allow only the specified class types to get set to it. If the class type is a BBLib::Effortless class, hashes (serializations) may be passed in to the setter and they will automatically be instantiatedas the object type (if able).
292
+
293
+ ```ruby
294
+ # Usage: attr_of <class>, <method_name>, [options]
295
+ # attr_of [<class1>, <class2>], <method_name>, [options]
296
+ attr_of Regexp, :expression, required: true
297
+ attr_of [String, Symbol], :attribute, default: :general
298
+ ```
299
+
300
+ The following special options are available to attr_of:
301
+ - __pack__: [true/false] When set to false the behavior that allows hashes to be used as constructor arguments for a Effortless class will be disabled and allowed classes will have to already be instantiated before being passed to the setter. (default is true)
302
+ - __suppress__: [true/false] By default if an object is passed to the setter that is not an object matching any of the allowed classes an exception is raised. Setting suppress to true will disable this behavior and instead the invalid object will simply be ignored (not set). (default is false)
303
+
304
+ ##### attr_array_of
305
+
306
+ __attr_array_of__ or __attr_ary_of__ create a getter and setter for an Array that will only allow certain types of Objects to be stored in it. It works very similarly to __attr_array__ otherwise. If one of the allowed classes is a BBLib::Effortless class, this method can accept hashes and will attempt to instantiate objects uses the hashes as constructor arguments (similar to __attr_of__).
307
+
308
+ ```ruby
309
+ # Usage: attr_ary_of <class>, <method_name>, [options]
310
+ # attr_ary_of [<class1>, <class2>, <...>], <method_name>, [options]
311
+ attr_ary_of String, :names, uniq: true
312
+ attr_ary_of [Integer, Float], :scores, add_rem: true
313
+ ```
314
+
315
+ The following special options are available to attr_array_of:
316
+ - __pack__: [true/false] When set to false the behavior that allows hashes to be used as constructor arguments for a Effortless class will be disabled and allowed classes will have to already be instantiated before being passed to the setter. (default is true)
317
+ - __suppress__: [true/false] By default if an object is passed to the setter that is not an object matching any of the allowed classes an exception is raised. Setting suppress to true will disable this behavior and instead the invalid object will simply be ignored. (default is false)
318
+ - __uniq__: [true/false] Ensures all items inside the array are unique. (default is false)
319
+ - __add_rem__: [true/false] Automatically creates an adder and remover method. They will be named add_<method_name> and remove_<method_name> by default. Naming can be defined in the adder_name and remover_name options. (default is false)
320
+ - __adder_name__: [String, Symbol] Sets a custom name for the adder method. add_rem must be set to true for this to matter.
321
+ - __remover_name__: [String, Symbol] Sets a custom name for the remover method. add_rem must be set to true for this to matter.
322
+
323
+ ##### attr_element_of
324
+
325
+ __attr_element_of__ creates a getter and setter that allow only specific objects from an array to be passed to the setter. This is great for creating enumerators.
326
+
327
+ ```ruby
328
+ # Usage: attr_element_of <element_array>, <method_name>, [options]
329
+ # attr_element_of <element_proc+_or_symbol>, <method_name>, [options]
330
+ METHODS = [:get, :post, :put, :delete, :head].freeze
331
+
332
+ attr_element_of METHODS, :http_method, default: METHODS.first
333
+
334
+ # A Proc can be passed instead of an array but it's result should be an Array.
335
+ # This allows for the Element list to be more dynamic (such as being loaded from a file like below).
336
+ # If a Symbol is passed, it is sent to the class as a method to get a list.
337
+ attr_element_of proc { File.read('states.txt').split("\n") }, :state
338
+ ```
339
+
340
+ - *There are no special options for __attr_element_of__*
341
+
342
+ ##### attr_elements_of
343
+
344
+ __attr_elements_of__ is similar to attr_element_of except is stores an Array that only allows elements from the element list.
345
+
346
+ ```ruby
347
+ # Usage: attr_elements_of <element_array>, <method_name>, [options]
348
+ # attr_elements_of <element_proc_or_symbol>, <method_name>, [options]
349
+ FOODS = %w{apple orange banana pizza hamburger burrito donut}
350
+
351
+ attr_elements_of FOODS, :favorite_foods
352
+ ```
353
+
354
+ - *There are no special options for __attr_elements_of__*
355
+
356
+ ##### attr_file
357
+
358
+ __attr_file__ creates a getter and setter for a string, meant to be a valid path to a file. When the setter is called, an exception will be raised unless the string is a valid path to a file on disk.
359
+
360
+ ```ruby
361
+ # Usage: attr_file <method_name>, [options]
362
+ attr_file :config_file
363
+ ```
364
+
365
+ The following arguments are available for attr_file:
366
+ - __mkfile__: [true/false] When set to true, if a file does not exist at the specified path it will be created (via FileUtils.touch). (default is false)
367
+
368
+ ##### attr_dir
369
+
370
+ attr_dir creates a getter and setter for a string, meant to be a valid path to a directory. When the setter is called, an exception will be raised unless the string is a valid path to a directory on disk.
371
+
372
+ ```ruby
373
+ # Usage: attr_file <method_name>, [options]
374
+ attr_dir :configs, default: Dir.pwd
375
+ ```
376
+
377
+ The following arguments are available for attr_dir:
378
+ - __mkpath__: [true/false] When set to true, if a path passed to the setter does not exist it will atempt to create it. (default is false)
379
+
380
+ ##### attr_time && attr_date
381
+
382
+ __attr_time__ creates a getter and setter that stores a Time object. It provides basic parsing so it can accept strings and numbers to generate Time objects. By default this will try Time.parse for strings and Time.at for Numerics. Custom formats can also be passed in if the format is not recognized correctly by Time.parse. __attr_date__ does the same thing, but instead stores a Date object.
383
+
384
+ ```ruby
385
+ # Usage: attr_time <method_name>, [options]
386
+ # attr_date <method_name>, [options]
387
+ attr_time :created_at, default_proc: proc { Time.now }
388
+ attr_date :release_date, formats: ['%Y-%m-%d', '%Y/%m/%d']
389
+ ```
390
+
391
+ The following arguments are available for attr_time and attr_date:
392
+ - __formats__: [Array of Strings] Formats allows for custom Time or Date formats to be used when parsing. These formats will be passed to the strptime method in order until one successfully creates a Time or Date object.
393
+
394
+ #### Simple Init
395
+
396
+ Simple Init is included in Effortless and provides an automatically constructed initialize method for all of the attr methods declared on the class. With Simple Init you will never need to write another initialize method again. How simple init interacts with BBLib::Attrs is described above but there are several other features showcased below.
397
+
398
+ ```ruby
399
+ class Movie
400
+ include BBLib::Effortless
401
+ attr_str :title, arg_at: 0, required: true
402
+ attr_str :description
403
+ attr_int :duration
404
+ attr_date :release_date
405
+ end
406
+
407
+ movie = Movie.new(title: 'Mad Max', duration: 96, release_date: '03-21-1980')
408
+ puts movie.title
409
+ # => Mad Max
410
+
411
+ # Since we added the :arg_at option to :title and told it to look for
412
+ # args at position 0, we can also pass the title as the first argument
413
+ # to the constructor without naming it.
414
+ movie = Movie.new('Toy Story 3')
415
+ puts movie.title
416
+ # => Toy Story 3
417
+
418
+ # We set the required: option to true on :title so SimpleInit will
419
+ # raise an exception if it is missing.
420
+ movie = Movie.new
421
+ # => ERROR: You are missing the following required argument for Movie: title (ArgumentError)
422
+
423
+ # By default if an attribute is passed in that does not exist (like :rating below)
424
+ # then an exception is thrown. This is due to the init_type which by default is set
425
+ # to :strict
426
+ movie = Movie.new(title: 'Up', rating: 'PG')
427
+ # => ERROR: Undefined attribute rating= for class Movie. (ArgumentError)
428
+
429
+ # Here we reopen the Movie class and set the init_type to :loose which will
430
+ # ignore unrecognized named arguments (and drop them).
431
+ # NOTE: :strict and :loose are the only two init_types.
432
+ class Movie
433
+ init_type :loose
434
+ end
435
+
436
+ # Now rating no longer causes an error, and is instead ignored.
437
+ movie = Movie.new(title: 'Up', rating: 'PG')
438
+ puts movie.title
439
+ # => Up
440
+ ```
441
+
442
+ #### Family Tree
443
+
444
+ Family Tree is another mixin that is built in to Effortless. It adds several methods that allow for the discovery of subclasses and instantiations of a class.
445
+
446
+ ```ruby
447
+ class Animal
448
+ include BBLib::Effortless
449
+ end
450
+
451
+ class Cat < Animal; end
452
+ class Dog < Animal; end
453
+
454
+ # Find all classes that inherit from Animal
455
+ p Animal.descendants
456
+ # => [Dog, Cat]
457
+
458
+ array = [Cat.new, Dog.new]
459
+
460
+ # Find all active instances of Animal or its descendants
461
+ p Animal.instances
462
+ # => [#<Dog:0x0000000005979118>, #<Cat:0x0000000005979820>]
463
+
464
+ class Calico < Cat; end
465
+ class Tabby < Cat; end
466
+
467
+ # Same as first call, but now we see the subclasses of our subclasses
468
+ p Animal.descendants
469
+ # => [Dog, Cat, Tabby, Calico]
470
+
471
+ # Similar to descendants but only shows classes that directly inherit from
472
+ # Animal and not their subclasses as well
473
+ p Animal.direct_descendants
474
+ # => [Dog, Cat]
475
+ ```
476
+
477
+ NOTE: Family Tree can be added to classes without using Effortless by extending the BBLib::FamilyTree module.
478
+
479
+ #### Bridge
480
+
481
+ TODO
482
+
483
+ #### Hooks (before and after)
484
+
485
+ TODO
486
+
487
+ #### Serializer
488
+
489
+ TODO
490
+
27
491
  ### Hash Path
28
492
 
29
- HashPath is a set of functions, classes and extensions to the native ruby hash and array classes. It allows to items to be retrieved from a hash using a dot delimited syntax, similar to XPath for XML. It also provides methods for moving, copying and deleting paths within hashes as well as modifying the contents of nested paths with hashes.
493
+ HashPath is a set of functions, classes and extensions to the native ruby hash and array classes. It allows items to be retrieved from a hash using a dot delimited syntax. It serves a similar function as XPath does for XML. It also provides methods for moving, copying and deleting paths within hashes as well as modifying the contents of nested paths with hashes.
30
494
 
31
495
  Below are several examples.
32
496
 
@@ -81,7 +545,9 @@ tree.find('e..a').first.siblings # Get siblings. next_sibling and previous_sibli
81
545
  # => [test]
82
546
  ```
83
547
 
84
- ### String
548
+ ### String Methods
549
+
550
+ Below are examples of the methods BBLib provides to the String class or for working with Strings.
85
551
 
86
552
  ```ruby
87
553
  str = 'this is an example'
@@ -202,7 +668,27 @@ fm.set_weight(:numeric, 5) # Set numeric to a weight of 5
202
668
  fm.set_weight(:composition, 0) # Turn composition off
203
669
  ```
204
670
 
205
- ### File
671
+ ### Numeric Methods
672
+
673
+ TODO
674
+
675
+ ### OS / System Methods
676
+
677
+ TODO
678
+
679
+ ### Time Methods
680
+
681
+ TODO
682
+
683
+ ### Hash Methods
684
+
685
+ TODO
686
+
687
+ ### Array Methods
688
+
689
+ TODO
690
+
691
+ ### File Methods
206
692
 
207
693
  ```ruby
208
694
  # Scan a directory for files using filters. Can be toggled to be recursive.
@@ -232,6 +718,14 @@ BBLib.scan_dirs # Matches only directories, files are ignored
232
718
  # => 20447232.0
233
719
  ```
234
720
 
721
+ ### HTML Methods
722
+
723
+ TODO
724
+
725
+ ### Logging
726
+
727
+ TODO
728
+
235
729
  ## Development
236
730
 
237
731
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.