betterobject 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 17e2da8e7bbc0099c4d397ac0ecbc619ce9ba46c
4
+ data.tar.gz: 7b0350db719f6ba417e65e197032262a4507ce14
5
+ SHA512:
6
+ metadata.gz: aa69cb58b0152b7f729cb0a66f66eb737b2b701c5e6dd477f462fe313d18e157801ddd3024cf31582a1e1780005dae396c56539c56476611f28b90780c6453fe
7
+ data.tar.gz: 6fc1f62ef608d31bff14911771aa19d96f74d7bd741c732503a5f8c2d5c4d3414c29404a839cf9be9cb7443086a95de73dbc9a8e9145028caaff50d4888a4929
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ before_install: gem install bundler -v 1.11.2
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at bryan@bdlsys.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in betterobject.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Bryan Colvin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,584 @@
1
+ # Betterobject
2
+
3
+ This gem installs several class methods to Object which in turn generates both class and instance methods but only when you are ready.
4
+ In order to prevent name pollution, you have the ability to manage the generators to pick alternate names if you prefer.
5
+ After scouring the RubyGems site, some of the better Class upgrades are included here as well as some of my own.
6
+ The gem creates the backbone upon which future upgrades should be forthcoming.
7
+ As a teaser, some of the generators presently include: obj.local_methods, obj.inherited_methods, obj.in?, COBJ.comes_from?, COBJ.derives_from?, COBJ.define_presence_of, obj.find_def. This first release installs 14 generators.
8
+ Calling `Object.better_install_all` will install all of the generators.
9
+ You can also generate a subset by calling `Object.better_install :generator_name` or `Object.better_install array_of_gen_names`.
10
+ The generator names are also the method names which can be renamed by calling `Object.better_rename(old_name, new_name)`;
11
+ this must be done before you generate the method.
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ ```ruby
18
+ gem 'betterobject'
19
+ ```
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install betterobject
28
+
29
+ Or as a stand-alone:
30
+
31
+ $ require "betterobject"
32
+
33
+ ## Usage
34
+
35
+ The class methods installed on Object must be called before something useful will happen.
36
+ Somewhere in the installation, you will need to run the generators. If you open `irb`, you can try this:
37
+
38
+ ```ruby
39
+ require "betterobject" # load gem
40
+
41
+ Object.better_install_all # install all generators
42
+ 5.in? 1..9 # true ...
43
+ class Fred
44
+ def a
45
+ end
46
+ end
47
+ fred = Fred.new
48
+ fred.local_methods # [:a]
49
+ fred.inherited_methods # [bunch of stuff not including :a]
50
+ String.derives_from? Comparable # true
51
+ String.derives_from? String # false
52
+ String.comes_from? Comparable # true
53
+ String.comes_from? String # true
54
+
55
+ String.define_presence_of :i_am_a_string? # updates Object and String
56
+ "hello".i_am_a_string? # true
57
+ 1234.i_am_a_string? # false
58
+ Arrray.define_presence_of(:i_am_not_an_array?, false)
59
+ [1,2,3].i_am_not_an_array? # false
60
+ "".i_am_not_an_array? # true
61
+ ```
62
+
63
+ You can see the motivation. In the event that one of these generators conflicts with some other method, you can elect to not execute that generator.
64
+ Or if you really need the functionality, you can rename the generator. First close the `irb` then reopen it, then try this:
65
+
66
+ ```ruby
67
+ require "betterobject"
68
+
69
+ Object.better_rename(:in?, :in_the_thing_to_the_right?)
70
+ Object.better_rename(:local_methods, :methods_by_me)
71
+ Object.better_install [:in_the_thing_to_the_right?, :methods_by_me] # or better_install_all
72
+ 5.in? 1..9 # undefined method ...
73
+ 5.in_the_thing_to_the_right? 1..9 # true
74
+ "".local_methods # undefined method ...
75
+ "".methods_by_me # [...]
76
+ ```
77
+
78
+ You can control which methods names get generated. Now let's dive into the other class methods of `betterobject`.
79
+
80
+ #### Object class methods created from the `betterobject` gem
81
+ * `Object.better_installed_instance_methods`
82
+ * `Object.better_installed_class_methods`
83
+ * `Object.better_installed`
84
+ * `Object.better_explain`
85
+ * `Object.better_source_code`
86
+ * `Object.better_list`
87
+ * `Object.better_install`
88
+ * `Object.better_install_all`
89
+ * `Object.better_uninstall`
90
+ * `Object.better_uninstall_all`
91
+ * `Object.better_skip`
92
+ * `Object.better_unskip`
93
+ * `Object.better_skipped`
94
+ * `Object.better_rename`
95
+
96
+
97
+ Note that there are no instance methods created by this gem until you install a generator.
98
+ Also, each and every method must be called from Object.
99
+
100
+ #### Object.better_install_all
101
+
102
+ This will install every defined generator. In the event that a generator is renamed, the new name will be generated, while the old name
103
+ will no longer exist. This is similar to renaming a file. Note that the generator essence never goes away, as it will exist under some new name.
104
+ It is simply tucked away until needed. Also, generators marked as skipped will not be installed.
105
+
106
+ #### Object.better_skip(gen or [gen1, gen2, ...] or gen1, gen2, ...)
107
+
108
+ This is to prevent a generator from installing by adding a skip attribute.
109
+ Additionally, skipped generators cannot be uninstalled until the skip flag is removed.
110
+ If a generator is first installed then given this skip attribute, it cannot be uninstalled.
111
+ This acts as a protection.
112
+
113
+ #### Object.better_unskip(gen or [gen1, gen2, ...] or gen1, gen2, ...)
114
+
115
+ This removes the skip attribute enabling the generator to be installed or uninstalled.
116
+
117
+ #### Object.better_skipped
118
+
119
+ This returns an array of skipped generators.
120
+
121
+ #### Object.better_install(gen or [gen1, gen2, ...] or gen1, gen2, ...)
122
+
123
+ This will install a specific generator.
124
+ If you rename a generator, the old name no longer exists, so you must use the new name. See below:
125
+
126
+ ```ruby
127
+ Object.better_rename(:in?, :is_in?)
128
+ Object.better_install(:in?) # Error
129
+ Object.better_install(:is_in?) # true
130
+ Object.better_install(:is_in?) # false ... already installed
131
+
132
+ str = "The cat in the hat is back"
133
+ 'cat'.is_in? str # true
134
+ ```
135
+
136
+ #### Object.better_uninstall_all
137
+
138
+ This will remove all the generators from Object. Note that some generators spawn additional generators such as `:define_presence_of`.
139
+ If this generator is ever run, `Object.better_uninstall_all` will not remove these second generation methods.
140
+ Note that generators marked with the skip flag will not be uninstalled.
141
+
142
+ #### Object.better_uninstall(gen or [gen1, gen2, ...] or gen1, gen2, ...)
143
+
144
+ This will uninstall a specific generator or a set of generators.
145
+ This method returns false if the generator is skipped, or already uninstalled; otherwise true is returned.
146
+ If you installed a generator and wish to rename it, you must first uninstall it before you can rename it.
147
+ See below:
148
+
149
+ ```ruby
150
+ Object.better_install :local_methods
151
+ "a string".local_methods # [list of local methods]
152
+ Object.better_rename(:local_methods, :methods_by_me) # Error ... installed methods cannot be renamed
153
+ Object.better_uninstall :local_methods
154
+ Object.better_rename(:local_methods, :methods_by_me)
155
+ Object.better_install :methods_by_me
156
+ "a string".methods_by_me # [list of local methods]
157
+ ```
158
+
159
+ #### Object.better_list(include_skip=false)
160
+
161
+ This returns an array of generators that can be installed. Skipped generators can also be listed if you call this method with the value `true`.
162
+
163
+ #### Object.better_installed
164
+
165
+ This returns a list of installed generators. This does not list what the generators generate.
166
+
167
+ #### Object.better_installed_instance_methods
168
+
169
+ This gives us a list of generators that created instance methods. This does not list what the generators generate.
170
+
171
+ #### Object.better_installed_class_methods
172
+
173
+ This give us a list of generators that created class methods. This does not list what the generators generate.
174
+
175
+ #### Object.better_rename(old_name, new_name)
176
+
177
+ This allows us to rename a generator which in turn (most likely) renames what gets generated.
178
+ This is an important feature as placing methods at the Object level has the danger of bumping into potential name conflicts.
179
+ See the example below:
180
+
181
+ ```ruby
182
+ Object.better_list.each do |old_name|
183
+ new_name = ("bjc_" + old_name.to_s).to_sym # my initials
184
+ Object.better_rename(old_name, new_name)
185
+ end
186
+ Object.better_install_all
187
+ sorted_hash = {zoo:"animals", banana:"fruit"}.bjc_sort! # == {banana:"fruit", zoo:"animals"}
188
+ sorted_hash.bjc_tag? # false
189
+ sorted_hash.bjc_tag!
190
+ sorted_hash.bjc_tag? # true
191
+ :zoo.bjc_in? hash # true
192
+ ```
193
+
194
+ #### Object.better_explain(:generator_name, pts=true)
195
+
196
+ Calling this method without a generator name gives us a general list of the generators.
197
+ Further details are revealed when a generator name is provided. The last default parameter puts the string to STOUT when true; otherwise,
198
+ a string is returned.
199
+ See example below:
200
+
201
+ ```ruby
202
+ Object.better_explain(:in?) # obj.in?(enum) # ex: 3.in? [3,4,5] == true
203
+ ```
204
+
205
+ #### Object.better_source_code(:generator_name, return_string = false, inner_only = false, type=:code)
206
+
207
+ This will revel the source code for the generator. You can then copy and paste this in `irb` and experiment with it. See below:
208
+
209
+ ```ruby
210
+ Object.better_source_code(:in?)
211
+
212
+ class Object
213
+ def in?(enum)
214
+ enum.include? self
215
+ end
216
+ end
217
+ ```
218
+
219
+ The parameter `return_string` will return a string instance when set true.
220
+ The parameter `inner_only` when set true will remove the `class Object` and enclosing `end` statements.
221
+ The final parameter is set to either `:code` or `:rm` depending on if you need the creation code or the deletion code.
222
+
223
+ #### Object.better_define(meth_name, code, type, doc="*Undocumented*", rm_code=nil)
224
+
225
+ This installs a user-defined generator. As an example we will create a `whotheheckami` generator as follows.
226
+ ```ruby
227
+ doc = "same as .class"
228
+ type = :both # declares that :class and :instance will both be present
229
+ meth_name = :whotheheckami
230
+ code = "
231
+ def self.BO_METH_NAME
232
+ self.class
233
+ end
234
+ def BO_METH_NAME
235
+ self.class
236
+ end
237
+ "
238
+ Object.better_define(meth_name, code, type, doc)
239
+ Object.better_list.include? :whotheheckami # true
240
+ Object.better_install :whotheheckami
241
+ "".whotheheckami # String
242
+ String.whotheheckami # Class
243
+ ```
244
+
245
+ Note that we used the identifier name `BO_METH_NAME` instead of `whotheheckami`.
246
+ This allows our generator to be renamed.
247
+ Generally speaking, the generator name need not be coupled with the method name, but that is the convention.
248
+ Also, you can target a foreign object if you wish.
249
+ The following example demonstrates updating String and also decouples the rename associations.
250
+
251
+ ```ruby
252
+ doc = "some cool string methods"
253
+ type = :instance
254
+ meth_name = :string_methods
255
+ code = "
256
+ String.class_eval do
257
+ def sort
258
+ self.split('').sort.join('')
259
+ end
260
+ def sort!
261
+ replace self.split('').sort.join('')
262
+ end
263
+ def histogram
264
+ hash = {}
265
+ self.split('').sort.each do |ch|
266
+ hash[ch] = hash[ch].nil? ? 1 : 1 + hash[ch]
267
+ end
268
+ return hash
269
+ end
270
+ end
271
+ "
272
+ rm_code = "
273
+ String.class_eval do
274
+ undef sort
275
+ undef sort!
276
+ undef histogram
277
+ end
278
+ "
279
+ Object.better_define(meth_name, code, type, doc, rm_code)
280
+ Object.better_list.include? :string_methods # true
281
+ Object.better_install :string_methods
282
+ "".string_methods # Error
283
+ "everybody".sort # "bdeeorvyy"
284
+ ```
285
+
286
+ In this case if you rename `:string_methods` you will only rename the generator.
287
+ This method was used as a tool to create some of the generators.
288
+ Note that if you decouple the method name from the generator name, or target a foreign object,
289
+ you must provide code to remove your methods.
290
+
291
+ #### Generator list
292
+ * `:local_methods`
293
+ * `:inherited_methods`
294
+ * `:replaced_methods`
295
+ * `:derives_from?`
296
+ * `:comes_from?`
297
+ * `:define_presence_of`
298
+ * `:in?`
299
+ * `:to_literal`
300
+ * `:pluralize`
301
+ * `:parent`
302
+ * `:sort!`
303
+ * `:find_def`
304
+ * `:tag`
305
+ * `:functionize`
306
+
307
+
308
+ #### Generator :local_methods(include_singleton_methods=true)
309
+
310
+ This is an instance generator on Object. It is used on all objects that derive from Object (which is pretty much everything).
311
+ The purpose is to view methods generated by the class of the instance and not the methods inherited by that class.
312
+ This reduces the clutter considerably while introspecting the methods. See the example below:
313
+
314
+ ```ruby
315
+ Object.better_install :local_methods # run the generator
316
+
317
+ class Fred < String
318
+ def a
319
+ end
320
+ def b
321
+ end
322
+ end
323
+
324
+ fred = Fred.new
325
+ def fred.c; end
326
+ fred.singleton_methods # [:c]
327
+ fred.local_methods # [:a, :b, :c]
328
+ fred.local_methods(false) #[:a, :b]
329
+ fred.methods # [:a, :b, :dup, :clone, etc ...]
330
+ ```
331
+
332
+ #### Generator :inherited_methods
333
+
334
+ This is an instance generator on Object. It is similar to `#methods`, except all locally defined methods are excluded.
335
+ The combination of `#local_methods` and `#inherited_methods` is the same as `#methods`. See below:
336
+
337
+ ```ruby
338
+ Object.better_install [:local_methods, :inherited_methods]
339
+
340
+ class Fred < String
341
+ def a
342
+ end
343
+ def b
344
+ end
345
+ end
346
+
347
+ fred = Fred.new
348
+ fred.methods.sort == [fred.local_methods + fred.inherited_methods].sort # true
349
+ ```
350
+
351
+ #### Generator :replaced_methods
352
+
353
+ This is an instance generator on Object. This lets us discover which methods have been replaced during inheritance, or replaced due to a singleton method using the same name as an instance method. See the example below:
354
+
355
+ ```ruby
356
+ Object.better_install :replaced_methods
357
+
358
+ class Fred < String
359
+ def length
360
+ end
361
+ end
362
+
363
+ fred = Fred.new
364
+ def fred.to_s
365
+ end
366
+
367
+ fred.replaced_methods # [:length, :to_s]
368
+ ```
369
+
370
+ #### Generators :derives_from? and :comes_from?
371
+
372
+ These methods are both class methods on Object. The purpose is to test hierarchy of derived objects.
373
+ The two class methods once generated are identical except `comes_from?` is more inclusive.
374
+ See the example below:
375
+
376
+ ```ruby
377
+ Object.better_install :derives_from?, :comes_from?
378
+
379
+ class Fred < String
380
+ def a
381
+ end
382
+ def b
383
+ end
384
+ end
385
+
386
+ Fred.derives_from? String # true
387
+ Fred.derives_from? Fred # false
388
+ Fred.derives_from? Object # true
389
+ Fred.comes_from? Fred # true
390
+ Fred.comes_from? String # true
391
+ Fred.comes_from? Object # true
392
+ ```
393
+
394
+ #### Generators :define_presence_of(:target_method_name, target_default_value = true)
395
+
396
+ This generator generates a generator!
397
+ When installed, a class method is created on Object called `#define_presence_of`.
398
+ This is called from a derived class such as String or Integer.
399
+ The intent is to create a test for a certain type.
400
+ This is a short-hand way of using the `#kind_of(CLASS_NAME)` method.
401
+ See the example below:
402
+
403
+ ```ruby
404
+
405
+ t1 = "fred"
406
+ t2 = 123
407
+ t1.kind_of? String # true ... old way of doing things
408
+ t2.kind_of? String # false
409
+
410
+ Object.better_install :define_presence_of
411
+
412
+ String.define_presence_of(:string?)
413
+ String.define_presence_of(:not_string?, false)
414
+ Integer.define_presence_of(:int?, true)
415
+ Integer.define_presence_of(:not_int?, false)
416
+
417
+ t1.string? # true
418
+ t2.not_string? # true
419
+ t1.int? # false
420
+ t2.int? # true
421
+ [4].int? # false ... it is an array
422
+ ```
423
+
424
+ As we can see from the above code, we now have a shorter way of doing type checking.
425
+ The generated generator defines an instance method on Object as well as the descendant class that calls it.
426
+ Each method returns an opposite result.
427
+ There are several base class gems (not mine) that force a certain naming convention; this one let's you pick the name!
428
+
429
+ #### Generators :in?
430
+
431
+ This generator allows us to swap the order of the standard `#include?` method with an improved comprehensive ordering.
432
+ I saw this in another gem called ("object-in" by Tim Rogers), so I give him credit for the idea. It is included here because
433
+ it is cool. This is probably the best name, but others (which you could rename to) could be: `:member_of`, `:is_in?`, `:in`, or `:element_of`.
434
+ See the example below:
435
+
436
+ ```ruby
437
+
438
+ [1,2,3].include? 2 # true ... old way of doing things
439
+
440
+ Object.better_install :in?
441
+
442
+ 2.in? [1,2,3] # true
443
+ 'i'.in? "team" # false
444
+ ```
445
+
446
+ #### Generators :pluralize(meth_name, alt=nil)
447
+
448
+ This generator installs a generator that mimics another method using a pluralized name.
449
+ One of my pet peves is poorly named methods that are grammatically incorrect.
450
+ From the String class, the method named `#start_with` should have been named `#starts_with`.
451
+ This class method can be called from Object, String, or any class you wish.
452
+ The pluralization is pretty smart, but if it does not quite work, you can provide the altername name in the second parameter. The new method name is returned. See the example below
453
+
454
+ ```ruby
455
+
456
+ Object.better_install :pluralize # installs the first-level generator
457
+ Object.pluralize :include? # returns :includes?
458
+ [1,2,3].includes? 2 # true
459
+
460
+ String.pluralize :start_with? # returns :starts_with?
461
+ "whatever".starts_with? "wh" # true
462
+
463
+ Object.pluralize :respond_to? # :responds_to?
464
+ 17.responds_to? :to_s # true
465
+ ```
466
+
467
+ #### Generators :parent
468
+
469
+ This generator finds the first non-module ancestor of a class.
470
+ The class Object's parent is always Object.
471
+ This is a class method installed on Object.
472
+
473
+ #### Generators :to_literal
474
+
475
+ This is an alias for `#inspect`. In the event inspect fails, `#to_s` is then called.
476
+
477
+ #### Generators :tag
478
+
479
+ This generator creates a family of instance methods. If unrenamed, you will get: `#tag`, `#tag!`, `#untag`, `#tag?` and `#tag=`.
480
+ If you rename this generator to :fred, you will get these: `#fred`, `#fred!`, `#unfred`, `#fred?`, `#fred=`.
481
+ Note that uninstall will remove all five methods even if renamed.
482
+ This method attaches a property to an instance of an Object or a derivative object.
483
+ Note that objects that have no constructors such as Integer, Float, NilClass, TrueClass, FalseClass and Symbol cannot be tagged.
484
+ Also, frozen object instances cannot be tagged.
485
+ You will need to place such objects either in a wrapper class or a use a container such as Array.
486
+ A good container system is the gem `primitive_wrapper`.
487
+ See the example below:
488
+
489
+ ```ruby
490
+ Object.better_install :tag
491
+
492
+ #tag get current tag value
493
+ #tag=(val) set tag's value to `val`
494
+ #tag! set tag's value to true ... same as #tag=true
495
+ #tag? returns true if tag's value is anything but nil, or false
496
+ #untag set tag's value to false ... same as #tag=false
497
+
498
+ var1 = "Something to remember"
499
+ var1.tag? # false
500
+ var1.tag # nil
501
+ var1.tag! # true
502
+ var1.tag # true
503
+ var1.tag? # true
504
+ var1.untag # false
505
+ var1.tag? # false
506
+ var1.tag= "don't forget me!"
507
+ var1.tag? # true
508
+ var1.tag # "don't forget me!"
509
+ var1.untag # false
510
+ var1.tag? # false
511
+ var1.tag # false
512
+ ```
513
+
514
+ #### Generators :sort!
515
+
516
+ This method targets only the Hash class and creates the `#sort!` method.
517
+ Hash has a method `#sort` that returns a sorted array of key value pairs.
518
+ Obviously, they omitted the self modifying version because `Arrays` are not `Hashes`.
519
+ See the example below:
520
+
521
+ ```ruby
522
+ hash = {:zoo=>"Animals", :fruit=>"Banana", :better=>"Object"}
523
+ hash.keys # [:zoo, :fruit, :better]
524
+ Object.better_install :sort!
525
+ Hash.respond_to? :sort! # true
526
+ hash.sort!
527
+ Hash.keys # [:better, :fruit, :zoo]
528
+ ```
529
+
530
+ #### Generators :find_def
531
+
532
+ This method locates the owner of either an instance method or a class method.
533
+ The method expects a symbol representation of the method.
534
+ The value `nil` is returned in the event that the method is undefined.
535
+ See the example below:
536
+
537
+ ```ruby
538
+ Object.better_install :find_def
539
+ tst = "".find_def :< # tst = Comparable
540
+ tst = 7.find_def :< # tst = Fixnum
541
+ tst = 7.find_def :to_int # tst = Integer
542
+ tst = 7.find_def :to_c # tst = Numeric
543
+ tst = Fixnum.find_def :to_s # tst = Module
544
+ tst = Fixnum.find_def :new # tst = nil
545
+ tst = "nope".find_def :foo # tst = nil
546
+ ```
547
+
548
+ #### Generators :functionize(meth = :new)
549
+
550
+ This method makes your class look like a method that you simply call on the class constant.
551
+ If you examine the `Rational` class, there is no `#new` constructor at all.
552
+ Instead, you call `Rational(2,3)` which creates the object.
553
+ On your own class object, the default will call `#new` adding shorter syntax candy.
554
+ This allows less typing to create the object.
555
+ You can also provide any class method you wish, but because you only get one, probably best if it were a constructor.
556
+ See the example below:
557
+
558
+ ```ruby
559
+ Object.better_install :functionize
560
+ class Clown
561
+ def initialize(prm1, prm2)
562
+ @prms = [prm1, prm2]
563
+ end
564
+ end
565
+
566
+ Clown.functionize
567
+ obj1 = Clown(:one, :two) # fast way
568
+ obj2 = Clown.new(:three, :four) # slow way
569
+ ```
570
+
571
+ ## Development
572
+
573
+ 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.
574
+
575
+ To install this gem onto your local machine, run `bundle exec rake install`.
576
+
577
+ ## Contributing
578
+
579
+ I need to control this for the time being.
580
+
581
+ ## License
582
+
583
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
584
+