[rubygems/rubygems] Use a constant empty tar header to avoid extra allocations
[ruby.git] / kernel.rb
blob541d0cfd9d11bf15a53e07c2fb702f7eeac459a3
1 module Kernel
2   #
3   #  call-seq:
4   #     obj.class    -> class
5   #
6   #  Returns the class of <i>obj</i>. This method must always be called
7   #  with an explicit receiver, as #class is also a reserved word in
8   #  Ruby.
9   #
10   #     1.class      #=> Integer
11   #     self.class   #=> Object
12   #--
13   # Equivalent to \c Object\#class in Ruby.
14   #
15   # Returns the class of \c obj, skipping singleton classes or module inclusions.
16   #++
17   #
18   def class
19     Primitive.attr! :leaf
20     Primitive.cexpr! 'rb_obj_class(self)'
21   end
23   #
24   #  call-seq:
25   #     obj.clone(freeze: nil) -> an_object
26   #
27   #  Produces a shallow copy of <i>obj</i>---the instance variables of
28   #  <i>obj</i> are copied, but not the objects they reference.
29   #  #clone copies the frozen value state of <i>obj</i>, unless the
30   #  +:freeze+ keyword argument is given with a false or true value.
31   #  See also the discussion under Object#dup.
32   #
33   #     class Klass
34   #        attr_accessor :str
35   #     end
36   #     s1 = Klass.new      #=> #<Klass:0x401b3a38>
37   #     s1.str = "Hello"    #=> "Hello"
38   #     s2 = s1.clone       #=> #<Klass:0x401b3998 @str="Hello">
39   #     s2.str[1,4] = "i"   #=> "i"
40   #     s1.inspect          #=> "#<Klass:0x401b3a38 @str=\"Hi\">"
41   #     s2.inspect          #=> "#<Klass:0x401b3998 @str=\"Hi\">"
42   #
43   #  This method may have class-specific behavior.  If so, that
44   #  behavior will be documented under the #+initialize_copy+ method of
45   #  the class.
46   #
47   def clone(freeze: nil)
48     Primitive.rb_obj_clone2(freeze)
49   end
51   #
52   #  call-seq:
53   #     obj.frozen?    -> true or false
54   #
55   #  Returns the freeze status of <i>obj</i>.
56   #
57   #     a = [ "a", "b", "c" ]
58   #     a.freeze    #=> ["a", "b", "c"]
59   #     a.frozen?   #=> true
60   #--
61   # Determines if the object is frozen. Equivalent to `Object#frozen?` in Ruby.
62   # @param[in] obj  the object to be determines
63   # @retval Qtrue if frozen
64   # @retval Qfalse if not frozen
65   #++
66   #
67   def frozen?
68     Primitive.attr! :leaf
69     Primitive.cexpr! 'rb_obj_frozen_p(self)'
70   end
72   #
73   #  call-seq:
74   #     obj.tap {|x| block }    -> obj
75   #
76   #  Yields self to the block, and then returns self.
77   #  The primary purpose of this method is to "tap into" a method chain,
78   #  in order to perform operations on intermediate results within the chain.
79   #
80   #     (1..10)                  .tap {|x| puts "original: #{x}" }
81   #       .to_a                  .tap {|x| puts "array:    #{x}" }
82   #       .select {|x| x.even? } .tap {|x| puts "evens:    #{x}" }
83   #       .map {|x| x*x }        .tap {|x| puts "squares:  #{x}" }
84   #
85   #--
86   # \private
87   #++
88   #
89   def tap
90     Primitive.attr! :inline_block
91     yield(self)
92     self
93   end
95   #
96   #  call-seq:
97   #     obj.then {|x| block }          -> an_object
98   #
99   #  Yields self to the block and returns the result of the block.
100   #
101   #     3.next.then {|x| x**x }.to_s             #=> "256"
102   #
103   #  Good usage for +then+ is value piping in method chains:
104   #
105   #     require 'open-uri'
106   #     require 'json'
107   #
108   #     construct_url(arguments).
109   #       then {|url| URI(url).read }.
110   #       then {|response| JSON.parse(response) }
111   #
112   #  When called without block, the method returns +Enumerator+,
113   #  which can be used, for example, for conditional
114   #  circuit-breaking:
115   #
116   #     # meets condition, no-op
117   #     1.then.detect(&:odd?)            # => 1
118   #     # does not meet condition, drop value
119   #     2.then.detect(&:odd?)            # => nil
120   #
121   #  Good usage for +then+ is value piping in method chains:
122   #
123   #     require 'open-uri'
124   #     require 'json'
125   #
126   #     construct_url(arguments).
127   #       then {|url| URI(url).read }.
128   #       then {|response| JSON.parse(response) }
129   #
130   def then
131     Primitive.attr! :inline_block
132     unless defined?(yield)
133       return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)'
134     end
135     yield(self)
136   end
138   #
139   #  call-seq:
140   #     obj.yield_self {|x| block }    -> an_object
141   #
142   #  Yields self to the block and returns the result of the block.
143   #
144   #     "my string".yield_self {|s| s.upcase }   #=> "MY STRING"
145   #
146   def yield_self
147     Primitive.attr! :inline_block
148     unless defined?(yield)
149       return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)'
150     end
151     yield(self)
152   end
154   module_function
156   # call-seq:
157   #    loop { block }
158   #    loop            -> an_enumerator
159   #
160   # Repeatedly executes the block.
161   #
162   # If no block is given, an enumerator is returned instead.
163   #
164   #    loop do
165   #      print "Input: "
166   #      line = gets
167   #      break if !line or line =~ /^q/i
168   #      # ...
169   #    end
170   #
171   # StopIteration raised in the block breaks the loop.  In this case,
172   # loop returns the "result" value stored in the exception.
173   #
174   #    enum = Enumerator.new { |y|
175   #      y << "one"
176   #      y << "two"
177   #      :ok
178   #    }
179   #
180   #    result = loop {
181   #      puts enum.next
182   #    } #=> :ok
183   def loop
184     Primitive.attr! :inline_block
185     unless defined?(yield)
186       return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_f_loop_size)'
187     end
189     begin
190       while true
191         yield
192       end
193     rescue StopIteration => e
194       e.result
195     end
196   end
198   #
199   #  call-seq:
200   #     Float(arg, exception: true)    -> float or nil
201   #
202   #  Returns <i>arg</i> converted to a float. Numeric types are
203   #  converted directly, and with exception to String and
204   #  <code>nil</code> the rest are converted using
205   #  <i>arg</i><code>.to_f</code>.  Converting a String with invalid
206   #  characters will result in a ArgumentError.  Converting
207   #  <code>nil</code> generates a TypeError.  Exceptions can be
208   #  suppressed by passing <code>exception: false</code>.
209   #
210   #     Float(1)                 #=> 1.0
211   #     Float("123.456")         #=> 123.456
212   #     Float("123.0_badstring") #=> ArgumentError: invalid value for Float(): "123.0_badstring"
213   #     Float(nil)               #=> TypeError: can't convert nil into Float
214   #     Float("123.0_badstring", exception: false)  #=> nil
215   #
216   def Float(arg, exception: true)
217     if Primitive.mandatory_only?
218       Primitive.rb_f_float1(arg)
219     else
220       Primitive.rb_f_float(arg, exception)
221     end
222   end
224   # call-seq:
225   #   Integer(object, base = 0, exception: true) -> integer or nil
226   #
227   # Returns an integer converted from +object+.
228   #
229   # Tries to convert +object+ to an integer
230   # using +to_int+ first and +to_i+ second;
231   # see below for exceptions.
232   #
233   # With a non-zero +base+, +object+ must be a string or convertible
234   # to a string.
235   #
236   # ==== numeric objects
237   #
238   # With integer argument +object+ given, returns +object+:
239   #
240   #   Integer(1)                # => 1
241   #   Integer(-1)               # => -1
242   #
243   # With floating-point argument +object+ given,
244   # returns +object+ truncated to an integer:
245   #
246   #   Integer(1.9)              # => 1  # Rounds toward zero.
247   #   Integer(-1.9)             # => -1 # Rounds toward zero.
248   #
249   # ==== string objects
250   #
251   # With string argument +object+ and zero +base+ given,
252   # returns +object+ converted to an integer in base 10:
253   #
254   #   Integer('100')    # => 100
255   #   Integer('-100')   # => -100
256   #
257   # With +base+ zero, string +object+ may contain leading characters
258   # to specify the actual base (radix indicator):
259   #
260   #   Integer('0100')  # => 64  # Leading '0' specifies base 8.
261   #   Integer('0b100') # => 4   # Leading '0b', specifies base 2.
262   #   Integer('0x100') # => 256 # Leading '0x' specifies base 16.
263   #
264   # With a positive +base+ (in range 2..36) given, returns +object+
265   # converted to an integer in the given base:
266   #
267   #   Integer('100', 2)   # => 4
268   #   Integer('100', 8)   # => 64
269   #   Integer('-100', 16) # => -256
270   #
271   # With a negative +base+ (in range -36..-2) given, returns +object+
272   # converted to an integer in the radix indicator if exists or
273   # +-base+:
274   #
275   #   Integer('0x100', -2)   # => 256
276   #   Integer('100', -2)     # => 4
277   #   Integer('0b100', -8)   # => 4
278   #   Integer('100', -8)     # => 64
279   #   Integer('0o100', -10)  # => 64
280   #   Integer('100', -10)    # => 100
281   #
282   # +base+ -1 is equal the -10 case.
283   #
284   # When converting strings, surrounding whitespace and embedded underscores
285   # are allowed and ignored:
286   #
287   #   Integer(' 100 ')      # => 100
288   #   Integer('-1_0_0', 16) # => -256
289   #
290   # ==== other classes
291   #
292   # Examples with +object+ of various other classes:
293   #
294   #   Integer(Rational(9, 10)) # => 0  # Rounds toward zero.
295   #   Integer(Complex(2, 0))   # => 2  # Imaginary part must be zero.
296   #   Integer(Time.now)        # => 1650974042
297   #
298   # ==== keywords
299   #
300   # With optional keyword argument +exception+ given as +true+ (the default):
301   #
302   # - Raises TypeError if +object+ does not respond to +to_int+ or +to_i+.
303   # - Raises TypeError if +object+ is +nil+.
304   # - Raise ArgumentError if +object+ is an invalid string.
305   #
306   # With +exception+ given as +false+, an exception of any kind is suppressed
307   # and +nil+ is returned.
309   def Integer(arg, base = 0, exception: true)
310     if Primitive.mandatory_only?
311       Primitive.rb_f_integer1(arg)
312     else
313       Primitive.rb_f_integer(arg, base, exception);
314     end
315   end