[rubygems/rubygems] Use a constant empty tar header to avoid extra allocations
[ruby.git] / array.rb
blobf63ff000568186a755c743e25c1195ce52406558
1 class Array
2   # call-seq:
3   #   array.each {|element| ... } -> self
4   #   array.each -> Enumerator
5   #
6   # Iterates over array elements.
7   #
8   # When a block given, passes each successive array element to the block;
9   # returns +self+:
10   #
11   #   a = [:foo, 'bar', 2]
12   #   a.each {|element|  puts "#{element.class} #{element}" }
13   #
14   # Output:
15   #
16   #   Symbol foo
17   #   String bar
18   #   Integer 2
19   #
20   # Allows the array to be modified during iteration:
21   #
22   #   a = [:foo, 'bar', 2]
23   #   a.each {|element| puts element; a.clear if element.to_s.start_with?('b') }
24   #
25   # Output:
26   #
27   #   foo
28   #   bar
29   #
30   # When no block given, returns a new Enumerator:
31   #   a = [:foo, 'bar', 2]
32   #
33   #   e = a.each
34   #   e # => #<Enumerator: [:foo, "bar", 2]:each>
35   #   a1 = e.each {|element|  puts "#{element.class} #{element}" }
36   #
37   # Output:
38   #
39   #   Symbol foo
40   #   String bar
41   #   Integer 2
42   #
43   # Related: #each_index, #reverse_each.
44   def each
45     Primitive.attr! :inline_block
46     Primitive.attr! :use_block
48     unless defined?(yield)
49       return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, ary_enum_length)'
50     end
51     _i = 0
52     value = nil
53     while Primitive.cexpr!(%q{ ary_fetch_next(self, LOCAL_PTR(_i), LOCAL_PTR(value)) })
54       yield value
55     end
56     self
57   end
59   # call-seq:
60   #    array.shuffle!(random: Random) -> array
61   #
62   # Shuffles the elements of +self+ in place.
63   #    a = [1, 2, 3] #=> [1, 2, 3]
64   #    a.shuffle!    #=> [2, 3, 1]
65   #    a             #=> [2, 3, 1]
66   #
67   # The optional +random+ argument will be used as the random number generator:
68   #    a.shuffle!(random: Random.new(1))  #=> [1, 3, 2]
69   def shuffle!(random: Random)
70     Primitive.rb_ary_shuffle_bang(random)
71   end
73   # call-seq:
74   #    array.shuffle(random: Random) -> new_ary
75   #
76   # Returns a new array with elements of +self+ shuffled.
77   #    a = [1, 2, 3] #=> [1, 2, 3]
78   #    a.shuffle     #=> [2, 3, 1]
79   #    a             #=> [1, 2, 3]
80   #
81   # The optional +random+ argument will be used as the random number generator:
82   #    a.shuffle(random: Random.new(1))  #=> [1, 3, 2]
83   def shuffle(random: Random)
84     Primitive.rb_ary_shuffle(random)
85   end
87   # call-seq:
88   #    array.sample(random: Random) -> object
89   #    array.sample(n, random: Random) -> new_ary
90   #
91   # Returns random elements from +self+.
92   #
93   # When no arguments are given, returns a random element from +self+:
94   #    a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
95   #    a.sample # => 3
96   #    a.sample # => 8
97   # If +self+ is empty, returns +nil+.
98   #
99   # When argument +n+ is given, returns a new +Array+ containing +n+ random
100   # elements from +self+:
101   #    a.sample(3) # => [8, 9, 2]
102   #    a.sample(6) # => [9, 6, 10, 3, 1, 4]
103   # Returns no more than <tt>a.size</tt> elements
104   # (because no new duplicates are introduced):
105   #    a.sample(a.size * 2) # => [6, 4, 1, 8, 5, 9, 10, 2, 3, 7]
106   # But +self+ may contain duplicates:
107   #    a = [1, 1, 1, 2, 2, 3]
108   #    a.sample(a.size * 2) # => [1, 1, 3, 2, 1, 2]
109   # The argument +n+ must be a non-negative numeric value.
110   # The order of the result array is unrelated to the order of +self+.
111   # Returns a new empty +Array+ if +self+ is empty.
112   #
113   # The optional +random+ argument will be used as the random number generator:
114   #    a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
115   #    a.sample(random: Random.new(1))     #=> 6
116   #    a.sample(4, random: Random.new(1))  #=> [6, 10, 9, 2]
117   def sample(n = (ary = false), random: Random)
118     if Primitive.mandatory_only?
119       # Primitive.cexpr! %{ rb_ary_sample(self, rb_cRandom, Qfalse, Qfalse) }
120       Primitive.ary_sample0
121     else
122       # Primitive.cexpr! %{ rb_ary_sample(self, random, n, ary) }
123       Primitive.ary_sample(random, n, ary)
124     end
125   end
127   # call-seq:
128   #   array.first -> object or nil
129   #   array.first(n) -> new_array
130   #
131   # Returns elements from +self+; does not modify +self+.
132   #
133   # When no argument is given, returns the first element:
134   #
135   #   a = [:foo, 'bar', 2]
136   #   a.first # => :foo
137   #   a # => [:foo, "bar", 2]
138   #
139   # If +self+ is empty, returns +nil+.
140   #
141   # When non-negative Integer argument +n+ is given,
142   # returns the first +n+ elements in a new +Array+:
143   #
144   #   a = [:foo, 'bar', 2]
145   #   a.first(2) # => [:foo, "bar"]
146   #
147   # If <tt>n >= array.size</tt>, returns all elements:
148   #
149   #   a = [:foo, 'bar', 2]
150   #   a.first(50) # => [:foo, "bar", 2]
151   #
152   # If <tt>n == 0</tt> returns an new empty +Array+:
153   #
154   #   a = [:foo, 'bar', 2]
155   #   a.first(0) # []
156   #
157   # Related: #last.
158   def first n = unspecified = true
159     if Primitive.mandatory_only?
160       Primitive.attr! :leaf
161       Primitive.cexpr! %q{ ary_first(self) }
162     else
163       if unspecified
164         Primitive.cexpr! %q{ ary_first(self) }
165       else
166         Primitive.cexpr! %q{  ary_take_first_or_last_n(self, NUM2LONG(n), ARY_TAKE_FIRST) }
167       end
168     end
169   end
171   # call-seq:
172   #   array.last  -> object or nil
173   #   array.last(n) -> new_array
174   #
175   # Returns elements from +self+; +self+ is not modified.
176   #
177   # When no argument is given, returns the last element:
178   #
179   #   a = [:foo, 'bar', 2]
180   #   a.last # => 2
181   #   a # => [:foo, "bar", 2]
182   #
183   # If +self+ is empty, returns +nil+.
184   #
185   # When non-negative Integer argument +n+ is given,
186   # returns the last +n+ elements in a new +Array+:
187   #
188   #   a = [:foo, 'bar', 2]
189   #   a.last(2) # => ["bar", 2]
190   #
191   # If <tt>n >= array.size</tt>, returns all elements:
192   #
193   #   a = [:foo, 'bar', 2]
194   #   a.last(50) # => [:foo, "bar", 2]
195   #
196   # If <tt>n == 0</tt>, returns an new empty +Array+:
197   #
198   #   a = [:foo, 'bar', 2]
199   #   a.last(0) # []
200   #
201   # Related: #first.
202   def last n = unspecified = true
203     if Primitive.mandatory_only?
204       Primitive.attr! :leaf
205       Primitive.cexpr! %q{ ary_last(self) }
206     else
207       if unspecified
208         Primitive.cexpr! %q{ ary_last(self) }
209       else
210         Primitive.cexpr! %q{ ary_take_first_or_last_n(self, NUM2LONG(n), ARY_TAKE_LAST) }
211       end
212     end
213   end