array-hooked 1.0.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.
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,12 @@
1
+
2
+ == 6/14/2012
3
+
4
+ Initial release - split from compositing-array.
5
+
6
+ == 6/15/2012
7
+
8
+ Added missing :get_without_hooks and corresponding hooks.
9
+
10
+ == 6/30/2012
11
+
12
+ Renamed from hooked-array to array-hooked. File schema updated to reflect gem name.
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # Hooked Array #
2
+
3
+ http://rubygems.org/gems/array-hooked
4
+
5
+ # Description #
6
+
7
+ Provides ::Array::Hooked and ::HookedArray.
8
+
9
+ # Summary #
10
+
11
+ A subclass of Array that offers event hooks for pre-insert/pre-set/pre-delete, insert/set/delete. ::HookedArray offers implicit reference to a configuration instance.
12
+
13
+ # Install #
14
+
15
+ * sudo gem install array-hooked
16
+
17
+ # Usage #
18
+
19
+ Provides methods that can be overridden that will be called during every corresponding event:
20
+
21
+ * pre_set_hook
22
+ * post_set_hook
23
+ * pre_get_hook
24
+ * post_get_hook
25
+ * pre_delete_hook
26
+ * post_delete_hook
27
+
28
+ As a result, several internal perform methods have been created:
29
+
30
+ * perform_set_between_hooks
31
+ * perform_insert_between_hooks
32
+ * perform_delete_between_hooks
33
+
34
+ Also provides methods corresponding to each already-existing method + '_without_hooks', which causes methods to bypass hooks.
35
+
36
+ # License #
37
+
38
+ (The MIT License)
39
+
40
+ Copyright (c) Asher
41
+
42
+ Permission is hereby granted, free of charge, to any person obtaining
43
+ a copy of this software and associated documentation files (the
44
+ 'Software'), to deal in the Software without restriction, including
45
+ without limitation the rights to use, copy, modify, merge, publish,
46
+ distribute, sublicense, and/or sell copies of the Software, and to
47
+ permit persons to whom the Software is furnished to do so, subject to
48
+ the following conditions:
49
+
50
+ The above copyright notice and this permission notice shall be
51
+ included in all copies or substantial portions of the Software.
52
+
53
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
54
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
55
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
56
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
57
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
58
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
59
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,2 @@
1
+
2
+ require_relative 'array/hooked.rb'
@@ -0,0 +1,43 @@
1
+
2
+ require 'identifies_as'
3
+
4
+ # namespaces that have to be declared ahead of time for proper load order
5
+ require_relative './namespaces'
6
+
7
+ # source file requires
8
+ require_relative './requires.rb'
9
+
10
+ class ::Array::Hooked < ::Array
11
+
12
+ ###############################
13
+ # perform_set_between_hooks #
14
+ ###############################
15
+
16
+ # Alias to original :[]= method. Used to perform actual set between hooks.
17
+ # @param [Fixnum] index Index at which set is taking place.
18
+ # @param [Object] object Element being set.
19
+ # @return [Object] Element returned.
20
+ alias_method :perform_set_between_hooks, :[]=
21
+
22
+ ##################################
23
+ # perform_insert_between_hooks #
24
+ ##################################
25
+
26
+ # Alias to original :insert method. Used to perform actual insert between hooks.
27
+ # @param [Fixnum] index Index at which insert is taking place.
28
+ # @param [Array<Object>] objects Elements being inserted.
29
+ # @return [Object] Element returned.
30
+ alias_method :perform_insert_between_hooks, :insert
31
+
32
+ ##################################
33
+ # perform_delete_between_hooks #
34
+ ##################################
35
+
36
+ # Alias to original :delete method. Used to perform actual delete between hooks.
37
+ # @param [Fixnum] index Index at which delete is taking place.
38
+ # @return [Object] Element returned.
39
+ alias_method :perform_delete_between_hooks, :delete_at
40
+
41
+ include ::Array::Hooked::ArrayInterface
42
+
43
+ end
@@ -0,0 +1,1233 @@
1
+
2
+ module ::Array::Hooked::ArrayInterface
3
+
4
+ instances_identify_as!( ::Array::Hooked )
5
+
6
+ ###################################### Subclass Hooks ##########################################
7
+
8
+ ##################
9
+ # pre_set_hook #
10
+ ##################
11
+
12
+ # A hook that is called before setting a value; return value is used in place of object.
13
+ # @param [Fixnum] index Index at which set/insert is taking place.
14
+ # @param [Object] object Element being set/inserted.
15
+ # @param [true,false] is_insert Whether this set is inserting a new index.
16
+ # @return [true,false] Return value is used in place of object.
17
+ def pre_set_hook( index, object, is_insert = false )
18
+
19
+ return object
20
+
21
+ end
22
+
23
+ ###################
24
+ # post_set_hook #
25
+ ###################
26
+
27
+ # A hook that is called after setting a value.
28
+ # @param [Fixnum] index Index at which set/insert is taking place.
29
+ # @param [Object] object Element being set/inserted.
30
+ # @param [true,false] is_insert Whether this set is inserting a new index.
31
+ # @return [Object] Ignored.
32
+ def post_set_hook( index, object, is_insert = false )
33
+
34
+ return object
35
+
36
+ end
37
+
38
+ ##################
39
+ # pre_get_hook #
40
+ ##################
41
+
42
+ # A hook that is called before getting a value; if return value is false, get does not occur.
43
+ # @param [Fixnum] index Index at which set/insert is taking place.
44
+ # @return [true,false] If return value is false, get does not occur.
45
+ def pre_get_hook( index )
46
+
47
+ # false means get does not take place
48
+ return true
49
+
50
+ end
51
+
52
+ ###################
53
+ # post_get_hook #
54
+ ###################
55
+
56
+ # A hook that is called after getting a value.
57
+ # @param [Fixnum] index Index at which get is taking place.
58
+ # @param [Object] object Element being set/inserted.
59
+ # @return [Object] Object returned in place of get result.
60
+ def post_get_hook( index, object )
61
+
62
+ return object
63
+
64
+ end
65
+
66
+ #####################
67
+ # pre_delete_hook #
68
+ #####################
69
+
70
+ # A hook that is called before deleting a value; if return value is false, delete does not occur.
71
+ # @param [Fixnum] index Index at which delete is taking place.
72
+ # @return [true,false] If return value is false, delete does not occur.
73
+ def pre_delete_hook( index )
74
+
75
+ # false means delete does not take place
76
+ return true
77
+
78
+ end
79
+
80
+ ######################
81
+ # post_delete_hook #
82
+ ######################
83
+
84
+ # A hook that is called after deleting a value.
85
+ # @param [Fixnum] index Index at which delete took place.
86
+ # @param [Object] object Element deleted.
87
+ # @return [Object] Object returned in place of delete result.
88
+ def post_delete_hook( index, object )
89
+
90
+ return object
91
+
92
+ end
93
+
94
+ ##################################### Self Management ##########################################
95
+
96
+ ########
97
+ # [] #
98
+ ########
99
+
100
+ def []( index )
101
+
102
+ object = nil
103
+
104
+ should_get = true
105
+
106
+ unless @without_hooks
107
+ should_get = pre_get_hook( index )
108
+ end
109
+
110
+ if should_get
111
+
112
+ object = super( index )
113
+
114
+ unless @without_hooks
115
+ object = post_get_hook( index, object )
116
+ end
117
+
118
+ end
119
+
120
+ return object
121
+
122
+ end
123
+
124
+ #######################
125
+ # get_without_hooks #
126
+ #######################
127
+
128
+ # Alias to :[] that bypasses hooks.
129
+ # @param [Fixnum] index Index at which set is taking place.
130
+ # @return [Object] Element returned.
131
+ def get_without_hooks( index )
132
+
133
+ @without_hooks = true
134
+
135
+ self[ index ] = object
136
+
137
+ @without_hooks = false
138
+
139
+ return object
140
+
141
+ end
142
+
143
+ #########
144
+ # []= #
145
+ #########
146
+
147
+ def []=( index, object )
148
+
149
+ # we are either replacing or adding at the end
150
+ # if we are replacing we are either replacing a parent element or an element in self
151
+ # * if replacing parent element, track and exclude parent changes
152
+
153
+ unless @without_hooks
154
+ object = pre_set_hook( index, object, false )
155
+ end
156
+
157
+ perform_set_between_hooks( index, object )
158
+
159
+ unless @without_hooks
160
+ object = post_set_hook( index, object, false )
161
+ end
162
+
163
+ return object
164
+
165
+ end
166
+
167
+ #######################
168
+ # set_without_hooks #
169
+ #######################
170
+
171
+ # Alias to :[]= that bypasses hooks.
172
+ # @param [Fixnum] index Index at which set is taking place.
173
+ # @param [Object] object Element being set.
174
+ # @return [Object] Element returned.
175
+ def set_without_hooks( index, object )
176
+
177
+ @without_hooks = true
178
+
179
+ self[ index ] = object
180
+
181
+ @without_hooks = false
182
+
183
+ return object
184
+
185
+ end
186
+
187
+ ############
188
+ # insert #
189
+ ############
190
+
191
+ def insert( index, *objects )
192
+
193
+ objects_to_insert = nil
194
+ if @without_hooks
195
+ objects_to_insert = objects
196
+ else
197
+ objects_to_insert = [ ]
198
+ objects.each_with_index do |this_object, this_index|
199
+ this_insert_index = index + this_index
200
+ this_object = pre_set_hook( this_insert_index, this_object, true )
201
+ objects_to_insert.push( this_object )
202
+ end
203
+ end
204
+ objects = objects_to_insert
205
+
206
+ # if we have less elements in self than the index we are inserting at
207
+ # we need to make sure the nils inserted cascade
208
+ if index > count
209
+ nils_created = index - count
210
+ index -= nils_created
211
+ nils = [ ]
212
+ nils_created.times do |this_time|
213
+ nils.push( nil )
214
+ end
215
+ objects = nils.concat( objects )
216
+ end
217
+
218
+ perform_insert_between_hooks( index, *objects )
219
+
220
+ unless @without_hooks
221
+ objects.each_with_index do |this_object, this_index|
222
+ objects[ this_index ] = post_set_hook( index + this_index, this_object, true )
223
+ end
224
+ end
225
+
226
+ return objects
227
+
228
+ end
229
+
230
+ ##########################
231
+ # insert_without_hooks #
232
+ ##########################
233
+
234
+ # Alias to :insert that bypasses hooks.
235
+ # @param [Fixnum] index Index at which set is taking place.
236
+ # @param [Array<Object>] objects Elements being inserted.
237
+ # @return [Object] Element returned.
238
+ def insert_without_hooks( index, *objects )
239
+
240
+ @without_hooks = true
241
+
242
+ super( index, *objects )
243
+
244
+ @without_hooks = false
245
+
246
+ return objects
247
+
248
+ end
249
+
250
+ ##########
251
+ # push #
252
+ ##########
253
+
254
+ def push( *objects )
255
+
256
+ return insert( count, *objects )
257
+
258
+ end
259
+
260
+ alias_method :<<, :push
261
+
262
+ ########################
263
+ # push_without_hooks #
264
+ ########################
265
+
266
+ # Alias to :push that bypasses hooks.
267
+ # @param [Array<Object>] objects Elements being pushed.
268
+ # @return [Object] Element returned.
269
+ def push_without_hooks( *objects )
270
+
271
+ @without_hooks = true
272
+
273
+ push( *objects )
274
+
275
+ @without_hooks = false
276
+
277
+ return objects
278
+
279
+ end
280
+
281
+ ############
282
+ # concat #
283
+ ############
284
+
285
+ def concat( *arrays )
286
+
287
+ arrays.each do |this_array|
288
+ push( *this_array )
289
+ end
290
+
291
+ return self
292
+
293
+ end
294
+
295
+ alias_method :+, :concat
296
+
297
+ ##########################
298
+ # concat_without_hooks #
299
+ ##########################
300
+
301
+ # Alias to :concat that bypasses hooks.
302
+ # @param [Array<Object>] objects Elements being concatenated.
303
+ # @return [Object] Element returned.
304
+ def concat_without_hooks( *arrays )
305
+
306
+ @without_hooks = true
307
+
308
+ concat( *arrays )
309
+
310
+ @without_hooks = false
311
+
312
+ return arrays
313
+
314
+ end
315
+
316
+ ############
317
+ # delete #
318
+ ############
319
+
320
+ def delete( object )
321
+
322
+ return_value = nil
323
+
324
+ if index = index( object )
325
+ return_value = delete_at( index )
326
+ end
327
+
328
+ return return_value
329
+
330
+ end
331
+
332
+ ##########################
333
+ # delete_without_hooks #
334
+ ##########################
335
+
336
+ # Alias to :delete that bypasses hooks.
337
+ # @param [Object] object Element being deleted.
338
+ # @return [Object] Element returned.
339
+ def delete_without_hooks( object )
340
+
341
+ @without_hooks = true
342
+
343
+ return_value = delete( object )
344
+
345
+ @without_hooks = false
346
+
347
+ return return_value
348
+
349
+ end
350
+
351
+ ####################
352
+ # delete_objects #
353
+ ####################
354
+
355
+ def delete_objects( *objects )
356
+
357
+ return_value = nil
358
+
359
+ indexes = [ ]
360
+ objects.each do |this_object|
361
+ this_index = index( this_object )
362
+ if this_index
363
+ indexes.push( this_index )
364
+ end
365
+ end
366
+
367
+ unless indexes.empty?
368
+ return_value = delete_at_indexes( *indexes )
369
+ end
370
+
371
+ return return_value
372
+
373
+ end
374
+
375
+ ##################################
376
+ # delete_objects_without_hooks #
377
+ ##################################
378
+
379
+ # Alias to :delete that bypasses hooks and takes multiple objects.
380
+ # @param [Array<Object>] objects Elements being deleted.
381
+ # @return [Object] Element returned.
382
+ def delete_objects_without_hooks( *objects )
383
+
384
+ @without_hooks = true
385
+
386
+ return_value = delete_objects( *objects )
387
+
388
+ @without_hooks = false
389
+
390
+ return return_value
391
+
392
+ end
393
+
394
+ #######
395
+ # - #
396
+ #######
397
+
398
+ def -( *arrays )
399
+
400
+ arrays.each do |this_array|
401
+ delete_objects( *this_array )
402
+ end
403
+
404
+ return self
405
+
406
+ end
407
+
408
+ ###############
409
+ # delete_at #
410
+ ###############
411
+
412
+ def delete_at( index )
413
+
414
+ deleted_object = nil
415
+
416
+ if @without_hooks
417
+ pre_delete_hook_result = true
418
+ else
419
+ pre_delete_hook_result = pre_delete_hook( index )
420
+ end
421
+
422
+ if pre_delete_hook_result
423
+
424
+ deleted_object = perform_delete_between_hooks( index )
425
+
426
+ unless @without_hooks
427
+ deleted_object = post_delete_hook( index, deleted_object )
428
+ end
429
+
430
+ end
431
+
432
+ return deleted_object
433
+
434
+ end
435
+
436
+ #############################
437
+ # delete_at_without_hooks #
438
+ #############################
439
+
440
+ # Alias to :delete_at that bypasses hooks.
441
+ # @param [Fixnum] index Index to delete.
442
+ # @return [Object] Deleted element.
443
+ def delete_at_without_hooks( index )
444
+
445
+ @without_hooks = true
446
+
447
+ object = delete_at( index )
448
+
449
+ @without_hooks = false
450
+
451
+ return object
452
+
453
+ end
454
+
455
+ #######################
456
+ # delete_at_indexes #
457
+ #######################
458
+
459
+ def delete_at_indexes( *indexes )
460
+
461
+ indexes = indexes.sort.uniq.reverse
462
+
463
+ objects = [ ]
464
+
465
+ indexes.each do |this_index|
466
+ objects.push( delete_at( this_index ) )
467
+ end
468
+
469
+ return objects
470
+
471
+ end
472
+
473
+ #####################################
474
+ # delete_at_indexes_without_hooks #
475
+ #####################################
476
+
477
+ # Alias to :delete_at that bypasses hooks and takes multiple indexes.
478
+ # @param [Array<Fixnum>] index Index to delete.
479
+ # @return [Object] Deleted element.
480
+ def delete_at_indexes_without_hooks( *indexes )
481
+
482
+ @without_hooks = true
483
+
484
+ objects = delete_at_indexes( *indexes )
485
+
486
+ @without_hooks = false
487
+
488
+ return objects
489
+
490
+ end
491
+
492
+ ###############
493
+ # delete_if #
494
+ ###############
495
+
496
+ def delete_if
497
+
498
+ return to_enum unless block_given?
499
+
500
+ indexes = [ ]
501
+
502
+ self.each_with_index do |this_object, index|
503
+ if yield( this_object )
504
+ indexes.push( index )
505
+ end
506
+ end
507
+
508
+ delete_at_indexes( *indexes )
509
+
510
+ return self
511
+
512
+ end
513
+
514
+ #############################
515
+ # delete_if_without_hooks #
516
+ #############################
517
+
518
+ # Alias to :delete_if that bypasses hooks.
519
+ # @yield Block passed to :delete_if.
520
+ # @return [Object] Deleted element.
521
+ def delete_if_without_hooks( & block )
522
+
523
+ @without_hooks = true
524
+
525
+ delete_if( & block )
526
+
527
+ @without_hooks = false
528
+
529
+ return self
530
+
531
+ end
532
+
533
+ #############
534
+ # keep_if #
535
+ #############
536
+
537
+ def keep_if
538
+
539
+ indexes = [ ]
540
+
541
+ self.each_with_index do |this_object, index|
542
+ unless yield( this_object )
543
+ indexes.push( index )
544
+ end
545
+ end
546
+
547
+ delete_at_indexes( *indexes )
548
+
549
+ return self
550
+
551
+ end
552
+
553
+ ###########################
554
+ # keep_if_without_hooks #
555
+ ###########################
556
+
557
+ # Alias to :keep_if that bypasses hooks.
558
+ # @yield Block passed to :keep_if.
559
+ # @return [Object] Deleted element.
560
+ def keep_if_without_hooks( & block )
561
+
562
+ @without_hooks = true
563
+
564
+ keep_if( & block )
565
+
566
+ @without_hooks = false
567
+
568
+ return self
569
+
570
+ end
571
+
572
+ ##############
573
+ # compact! #
574
+ ##############
575
+
576
+ def compact!
577
+
578
+ return keep_if do |object|
579
+ object != nil
580
+ end
581
+
582
+ end
583
+
584
+ ############################
585
+ # compact_without_hooks! #
586
+ ############################
587
+
588
+ # Alias to :compact that bypasses hooks.
589
+ # @return [Object] Self.
590
+ def compact_without_hooks!
591
+
592
+ @without_hooks = true
593
+
594
+ compact!
595
+
596
+ @without_hooks = false
597
+
598
+ return self
599
+
600
+ end
601
+
602
+ ##############
603
+ # flatten! #
604
+ ##############
605
+
606
+ def flatten!
607
+
608
+ return_value = nil
609
+
610
+ indexes = [ ]
611
+
612
+ self.each_with_index do |this_object, index|
613
+ if this_object.is_a?( Array )
614
+ indexes.push( index )
615
+ end
616
+ end
617
+
618
+ unless indexes.empty?
619
+ indexes.sort!.reverse!
620
+ indexes.each do |this_index|
621
+ this_array = delete_at( this_index )
622
+ insert( this_index, *this_array )
623
+ end
624
+ return_value = self
625
+ end
626
+
627
+ return return_value
628
+
629
+ end
630
+
631
+ ############################
632
+ # flatten_without_hooks! #
633
+ ############################
634
+
635
+ # Alias to :flatten that bypasses hooks.
636
+ # @return [Object] Self.
637
+ def flatten_without_hooks!
638
+
639
+ @without_hooks = true
640
+
641
+ return_value = flatten!
642
+
643
+ @without_hooks = false
644
+
645
+ return return_value
646
+
647
+ end
648
+
649
+ #############
650
+ # reject! #
651
+ #############
652
+
653
+ def reject!
654
+
655
+ return to_enum unless block_given?
656
+
657
+ return_value = nil
658
+
659
+ deleted_objects = 0
660
+
661
+ iteration_dup = dup
662
+ iteration_dup.each_with_index do |this_object, index|
663
+ if yield( this_object )
664
+ delete_at( index - deleted_objects )
665
+ deleted_objects += 1
666
+ end
667
+ end
668
+
669
+ if deleted_objects > 0
670
+ return_value = self
671
+ end
672
+
673
+ return return_value
674
+
675
+ end
676
+
677
+ ###########################
678
+ # reject_without_hooks! #
679
+ ###########################
680
+
681
+ # Alias to :reject that bypasses hooks.
682
+ # @yield Block passed to :keep_if.
683
+ # @return [Object] Self.
684
+ def reject_without_hooks!( & block )
685
+
686
+ @without_hooks = true
687
+
688
+ reject!( & block )
689
+
690
+ @without_hooks = false
691
+
692
+ return return_value
693
+
694
+ end
695
+
696
+ #############
697
+ # replace #
698
+ #############
699
+
700
+ def replace( other_array )
701
+
702
+ clear
703
+
704
+ other_array.each_with_index do |this_object, index|
705
+ unless self[ index ] == this_object
706
+ self[ index ] = this_object
707
+ end
708
+ end
709
+
710
+ return self
711
+
712
+ end
713
+
714
+ ###########################
715
+ # replace_without_hooks #
716
+ ###########################
717
+
718
+ # Alias to :replace that bypasses hooks.
719
+ # @param [Array] other_array Other array to replace self with.
720
+ # @return [Object] Self.
721
+ def replace_without_hooks( other_array )
722
+
723
+ @without_hooks = true
724
+
725
+ replace( other_array )
726
+
727
+ @without_hooks = false
728
+
729
+ return self
730
+
731
+ end
732
+
733
+ ##############
734
+ # reverse! #
735
+ ##############
736
+
737
+ def reverse!
738
+
739
+ reversed_array = reverse
740
+
741
+ clear
742
+
743
+ reversed_array.each_with_index do |this_object, index|
744
+ self[ index ] = this_object
745
+ end
746
+
747
+ return self
748
+
749
+ end
750
+
751
+ ############################
752
+ # reverse_without_hooks! #
753
+ ############################
754
+
755
+ # Alias to :reverse that bypasses hooks.
756
+ # @return [Object] Self.
757
+ def reverse_without_hooks!
758
+
759
+ @without_hooks = true
760
+
761
+ reverse!
762
+
763
+ @without_hooks = false
764
+
765
+ return self
766
+
767
+ end
768
+
769
+ #############
770
+ # rotate! #
771
+ #############
772
+
773
+ def rotate!( rotate_count = 1 )
774
+
775
+ reversed_array = rotate( rotate_count )
776
+
777
+ clear
778
+
779
+ reversed_array.each_with_index do |this_object, index|
780
+ self[ index ] = this_object
781
+ end
782
+
783
+ return self
784
+
785
+ end
786
+
787
+ ###########################
788
+ # rotate_without_hooks! #
789
+ ###########################
790
+
791
+ # Alias to :rotate that bypasses hooks.
792
+ # @param [Fixnum] rotate_count Integer count of how many elements to rotate.
793
+ # @return [Object] Self.
794
+ def rotate_without_hooks!( rotate_count = 1 )
795
+
796
+ @without_hooks = true
797
+
798
+ rotate!( rotate_count )
799
+
800
+ @without_hooks = false
801
+
802
+ return self
803
+
804
+ end
805
+
806
+ #############
807
+ # select! #
808
+ #############
809
+
810
+ def select!
811
+
812
+ return to_enum unless block_given?
813
+
814
+ deleted_objects = 0
815
+
816
+ iteration_dup = dup
817
+ iteration_dup.each_with_index do |this_object, index|
818
+ unless yield( this_object )
819
+ delete_at( index - deleted_objects )
820
+ deleted_objects += 1
821
+ end
822
+ end
823
+
824
+ return self
825
+
826
+ end
827
+
828
+ ###########################
829
+ # select_without_hooks! #
830
+ ###########################
831
+
832
+ # Alias to :select that bypasses hooks.
833
+ # @yield Block passed to :select!.
834
+ # @return [Object] Self.
835
+ def select_without_hooks!( & block )
836
+
837
+ @without_hooks = true
838
+
839
+ select!( & block )
840
+
841
+ @without_hooks = false
842
+
843
+ return self
844
+
845
+ end
846
+
847
+ ##############
848
+ # shuffle! #
849
+ ##############
850
+
851
+ def shuffle!( random_number_generator = nil )
852
+
853
+ shuffled_array = shuffle( random: random_number_generator )
854
+
855
+ clear
856
+
857
+ shuffled_array.each_with_index do |this_object, index|
858
+ self[ index ] = this_object
859
+ end
860
+
861
+ return self
862
+
863
+ end
864
+
865
+ ############################
866
+ # shuffle_without_hooks! #
867
+ ############################
868
+
869
+ # Alias to :shuffle that bypasses hooks.
870
+ # @param [Object] random_number_generator Random number generator passed to :shuffle!.
871
+ # @return [Object] Self.
872
+ def shuffle_without_hooks!( random_number_generator = nil )
873
+
874
+ @without_hooks = true
875
+
876
+ shuffle!( random_number_generator )
877
+
878
+ @without_hooks = false
879
+
880
+ return self
881
+
882
+ end
883
+
884
+ ##############
885
+ # collect! #
886
+ # map! #
887
+ ##############
888
+
889
+ def collect!
890
+
891
+ return to_enum unless block_given?
892
+
893
+ self.each_with_index do |this_object, index|
894
+ replacement_object = yield( this_object )
895
+ self[ index ] = replacement_object
896
+ end
897
+
898
+ return self
899
+
900
+ end
901
+
902
+ alias_method :map!, :collect!
903
+
904
+ ############################
905
+ # collect_without_hooks! #
906
+ # map_without_hooks! #
907
+ ############################
908
+
909
+ # Alias to :select that bypasses hooks.
910
+ # @yield Block passed to :collect!.
911
+ # @return [Object] Self.
912
+ def collect_without_hooks!( & block )
913
+
914
+ @without_hooks = true
915
+
916
+ collect!( & block )
917
+
918
+ @without_hooks = false
919
+
920
+ return self
921
+
922
+ end
923
+
924
+ alias_method :map_without_hooks!, :collect_without_hooks!
925
+
926
+ ###########
927
+ # sort! #
928
+ ###########
929
+
930
+ def sort!( & block )
931
+
932
+ sorted_array = sort( & block )
933
+
934
+ unless sorted_array == self
935
+
936
+ replace( sorted_array )
937
+
938
+ end
939
+
940
+ return self
941
+
942
+ end
943
+
944
+ #########################
945
+ # sort_without_hooks! #
946
+ #########################
947
+
948
+ # Alias to :sort that bypasses hooks.
949
+ # @yield Block passed to :sort!.
950
+ # @return [Object] Self.
951
+ def sort_without_hooks!( & block )
952
+
953
+ @without_hooks = true
954
+
955
+ sort!
956
+
957
+ @without_hooks = false
958
+
959
+ return self
960
+
961
+ end
962
+
963
+ ##############
964
+ # sort_by! #
965
+ ##############
966
+
967
+ def sort_by!( & block )
968
+
969
+ return to_enum unless block_given?
970
+
971
+ sorted_array = sort_by( & block )
972
+
973
+ unless sorted_array == self
974
+
975
+ replace( sorted_array )
976
+
977
+ end
978
+
979
+ return self
980
+
981
+ end
982
+
983
+ ############################
984
+ # sort_by_without_hooks! #
985
+ ############################
986
+
987
+ # Alias to :sort_by! that bypasses hooks.
988
+ # @yield Block passed to :sort_by!.
989
+ # @return [Object] Self.
990
+ def sort_by_without_hooks!( & block )
991
+
992
+ @without_hooks = true
993
+
994
+ sort_by!( & block )
995
+
996
+ @without_hooks = false
997
+
998
+ return self
999
+
1000
+ end
1001
+
1002
+ ###########
1003
+ # uniq! #
1004
+ ###########
1005
+
1006
+ def uniq!
1007
+
1008
+ return_value = nil
1009
+
1010
+ uniq_array = uniq
1011
+
1012
+ unless uniq_array == self
1013
+
1014
+ clear
1015
+
1016
+ replace( uniq_array )
1017
+
1018
+ end
1019
+
1020
+ return return_value
1021
+
1022
+ end
1023
+
1024
+ #########################
1025
+ # uniq_without_hooks! #
1026
+ #########################
1027
+
1028
+ # Alias to :uniq! that bypasses hooks.
1029
+ # @return [Object] Self.
1030
+ def uniq_without_hooks!
1031
+
1032
+ @without_hooks = true
1033
+
1034
+ return_value = uniq!
1035
+
1036
+ @without_hooks = false
1037
+
1038
+ return return_value
1039
+
1040
+ end
1041
+
1042
+ #############
1043
+ # unshift #
1044
+ #############
1045
+
1046
+ def unshift( object )
1047
+
1048
+ insert( 0, object )
1049
+
1050
+ return self
1051
+
1052
+ end
1053
+
1054
+ ###########################
1055
+ # unshift_without_hooks #
1056
+ ###########################
1057
+
1058
+ # Alias to :unshift that bypasses hooks.
1059
+ # @param [Object] object Object to unshift onto self.
1060
+ # @return [Object] Self.
1061
+ def unshift_without_hooks( object )
1062
+
1063
+ @without_hooks = true
1064
+
1065
+ unshift( object )
1066
+
1067
+ @without_hooks = false
1068
+
1069
+ return self
1070
+
1071
+ end
1072
+
1073
+ #########
1074
+ # pop #
1075
+ #########
1076
+
1077
+ def pop
1078
+
1079
+ object = delete_at( count - 1 )
1080
+
1081
+ return object
1082
+
1083
+ end
1084
+
1085
+ #######################
1086
+ # pop_without_hooks #
1087
+ #######################
1088
+
1089
+ # Alias to :pop that bypasses hooks.
1090
+ # @return [Object] Self.
1091
+ def pop_without_hooks
1092
+
1093
+ @without_hooks = true
1094
+
1095
+ object = pop
1096
+
1097
+ @without_hooks = false
1098
+
1099
+ return object
1100
+
1101
+ end
1102
+
1103
+ ###########
1104
+ # shift #
1105
+ ###########
1106
+
1107
+ def shift
1108
+
1109
+ object = delete_at( 0 )
1110
+
1111
+ return object
1112
+
1113
+ end
1114
+
1115
+ #########################
1116
+ # shift_without_hooks #
1117
+ #########################
1118
+
1119
+ # Alias to :shift that bypasses hooks.
1120
+ # @return [Object] Self.
1121
+ def shift_without_hooks
1122
+
1123
+ @without_hooks = true
1124
+
1125
+ object = shift
1126
+
1127
+ @without_hooks = false
1128
+
1129
+ return object
1130
+
1131
+ end
1132
+
1133
+ ############
1134
+ # slice! #
1135
+ ############
1136
+
1137
+ def slice!( index_start_or_range, length = nil )
1138
+
1139
+ slice = nil
1140
+
1141
+ start_index = nil
1142
+ end_index = nil
1143
+
1144
+ if index_start_or_range.is_a?( Range )
1145
+
1146
+ start_index = index_start_or_range.begin
1147
+ end_index = index_start_or_range.end
1148
+
1149
+ elsif length
1150
+
1151
+ start_index = index_start_or_range
1152
+ end_index = index_start_or_range + length
1153
+
1154
+ end
1155
+
1156
+ if end_index
1157
+
1158
+ indexes = [ ]
1159
+
1160
+ ( end_index - start_index ).times do |this_time|
1161
+ indexes.push( end_index - this_time - 1 )
1162
+ end
1163
+
1164
+ slice = delete_at_indexes( *indexes )
1165
+
1166
+ else
1167
+
1168
+ slice = delete_at( start_index )
1169
+
1170
+ end
1171
+
1172
+
1173
+ return slice
1174
+
1175
+ end
1176
+
1177
+ ##########################
1178
+ # slice_without_hooks! #
1179
+ ##########################
1180
+
1181
+ # Alias to :slice! that bypasses hooks.
1182
+ # @param [Fixnum] index_start_or_range Index at which to begin slice.
1183
+ # @param [Fixnum] length Length of slice.
1184
+ # @return [Object] Self.
1185
+ def slice_without_hooks!( index_start_or_range, length = nil )
1186
+
1187
+ @without_hooks = true
1188
+
1189
+ slice = slice!( index_start_or_range, length )
1190
+
1191
+ @without_hooks = false
1192
+
1193
+ return slice
1194
+
1195
+ end
1196
+
1197
+ ###########
1198
+ # clear #
1199
+ ###########
1200
+
1201
+ def clear
1202
+
1203
+ indexes = [ ]
1204
+
1205
+ count.times do |this_time|
1206
+ indexes.push( count - this_time - 1 )
1207
+ end
1208
+
1209
+ delete_at_indexes( *indexes )
1210
+
1211
+ return self
1212
+
1213
+ end
1214
+
1215
+ #########################
1216
+ # clear_without_hooks #
1217
+ #########################
1218
+
1219
+ # Alias to :clear that bypasses hooks.
1220
+ # @return [Object] Self.
1221
+ def clear_without_hooks
1222
+
1223
+ @without_hooks = true
1224
+
1225
+ clear
1226
+
1227
+ @without_hooks = false
1228
+
1229
+ return self
1230
+
1231
+ end
1232
+
1233
+ end