* 2022-01-18 [ci skip]
[ruby-80x24.org.git] / kernel.rb
blob9cc58bc1d96985d3bdc248e7eaba613277ab1ee1
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! 'inline'
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 \c 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! 'inline'
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     yield(self)
91     self
92   end
94   #
95   #  call-seq:
96   #     obj.then {|x| block }          -> an_object
97   #
98   #  Yields self to the block and returns the result of the block.
99   #
100   #     3.next.then {|x| x**x }.to_s             #=> "256"
101   #
102   #  Good usage for +then+ is value piping in method chains:
103   #
104   #     require 'open-uri'
105   #     require 'json'
106   #
107   #     construct_url(arguments).
108   #       then {|url| URI(url).read }.
109   #       then {|response| JSON.parse(response) }
110   #
111   #  When called without block, the method returns +Enumerator+,
112   #  which can be used, for example, for conditional
113   #  circuit-breaking:
114   #
115   #     # meets condition, no-op
116   #     1.then.detect(&:odd?)            # => 1
117   #     # does not meet condition, drop value
118   #     2.then.detect(&:odd?)            # => nil
119   #
120   def then
121     unless Primitive.block_given_p
122       return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)'
123     end
124     yield(self)
125   end
127   #
128   #  call-seq:
129   #     obj.yield_self {|x| block }    -> an_object
130   #
131   #  Yields self to the block and returns the result of the block.
132   #
133   #     "my string".yield_self {|s| s.upcase }   #=> "MY STRING"
134   #
135   #  Good usage for +then+ is value piping in method chains:
136   #
137   #     require 'open-uri'
138   #     require 'json'
139   #
140   #     construct_url(arguments).
141   #       then {|url| URI(url).read }.
142   #       then {|response| JSON.parse(response) }
143   #
144   def yield_self
145     unless Primitive.block_given_p
146       return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)'
147     end
148     yield(self)
149   end
151   module_function
153   #
154   #  call-seq:
155   #     Float(arg, exception: true)    -> float or nil
156   #
157   #  Returns <i>arg</i> converted to a float. Numeric types are
158   #  converted directly, and with exception to String and
159   #  <code>nil</code> the rest are converted using
160   #  <i>arg</i><code>.to_f</code>.  Converting a String with invalid
161   #  characters will result in a ArgumentError.  Converting
162   #  <code>nil</code> generates a TypeError.  Exceptions can be
163   #  suppressed by passing <code>exception: false</code>.
164   #
165   #     Float(1)                 #=> 1.0
166   #     Float("123.456")         #=> 123.456
167   #     Float("123.0_badstring") #=> ArgumentError: invalid value for Float(): "123.0_badstring"
168   #     Float(nil)               #=> TypeError: can't convert nil into Float
169   #     Float("123.0_badstring", exception: false)  #=> nil
170   #
171   def Float(arg, exception: true)
172     if Primitive.mandatory_only?
173       Primitive.rb_f_float1(arg)
174     else
175       Primitive.rb_f_float(arg, exception)
176     end
177   end