forked from rubinius/rubinius
/
kernel19.rb
281 lines (233 loc) · 6.43 KB
/
kernel19.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# -*- encoding: us-ascii -*-
module Kernel
def method(name)
name = Rubinius::Type.coerce_to_symbol name
code = Rubinius.find_method(self, name)
if code
Method.new(self, code[1], code[0], name)
elsif respond_to_missing?(name, true)
Method.new(self, self.class, Rubinius::MissingMethod.new(self, name), name)
else
raise NameError, "undefined method `#{name}' for #{self.inspect}"
end
end
def public_method(name)
name = Rubinius::Type.coerce_to_symbol name
code = Rubinius.find_public_method(self, name)
if code
Method.new(self, code[1], code[0], name)
elsif respond_to_missing?(name, false)
Method.new(self, self.class, Rubinius::MissingMethod.new(self, name), name)
else
raise NameError, "undefined method `#{name}' for #{self.inspect}"
end
end
alias_method :__callee__, :__method__
module_function :__callee__
def define_singleton_method(*args, &block)
singleton_class.send(:define_method, *args, &block)
end
def loop
return to_enum(:loop) unless block_given?
begin
while true
yield
end
rescue StopIteration
end
end
module_function :loop
def rand(limit=0)
if limit.kind_of?(Range)
Thread.current.randomizer.random_range(limit)
else
unless limit == 0
limit = Integer(limit).abs
end
case limit
when 0
Thread.current.randomizer.random_float
when Integer
Thread.current.randomizer.random_integer(limit - 1)
else
raise TypeError, "Integer() returned a non-integer"
end
end
end
module_function :rand
def Integer(obj, base=nil)
if obj.kind_of? String
if obj.empty?
raise ArgumentError, "invalid value for Integer: (empty string)"
else
base ||= 0
return obj.to_inum(base, true)
end
end
if base
raise ArgumentError, "base is only valid for String values"
end
case obj
when Integer
obj
when Float
if obj.nan? or obj.infinite?
raise FloatDomainError, "unable to coerce #{obj} to Integer"
else
obj.to_int
end
when NilClass
raise TypeError, "can't convert nil into Integer"
else
# Can't use coerce_to or try_convert because I think there is an
# MRI bug here where it will return the value without checking
# the return type.
if obj.respond_to? :to_int
if val = obj.to_int
return val
end
end
Rubinius::Type.coerce_to obj, Integer, :to_i
end
end
module_function :Integer
def to_enum(method=:each, *args)
Enumerator.new(self, method, *args)
end
alias_method :enum_for, :to_enum
# Send message to object with given arguments.
#
# Ignores visibility of method, and may therefore be used to invoke
# protected or private methods.
#
# As denoted by the double-underscore, this method must not be removed or
# redefined by user code.
#
# In 1.8, :send is an alias to :__send__ because both methods are defined on
# Kernel. But in 1.9, :__send__ is defined on BasicObject.
#
def send(message, *args)
Rubinius.primitive :object_send
raise PrimitiveFailure, "Kernel#send primitive failed"
end
def public_send(message, *args)
Rubinius.primitive :object_public_send
raise PrimitiveFailure, "Kernel#public_send primitive failed"
end
# In 1.8, :object_id is an alias to :__id__ because both methods are defined
# on Kernel. But in 1.9, :__id__ is defined on BasicObject.
#
def object_id
Rubinius.primitive :object_id
raise PrimitiveFailure, "Kernel#object_id primitive failed"
end
def open(obj, *rest, &block)
if obj.respond_to?(:to_open)
obj = obj.to_open(*rest)
if block_given?
return yield(obj)
else
return obj
end
end
path = Rubinius::Type.coerce_to_path obj
if path.kind_of? String and path.prefix? '|'
return IO.popen(path[1..-1], *rest, &block)
end
File.open(path, *rest, &block)
end
module_function :open
# Attempt to load the given file, returning true if successful. Works just
# like Kernel#require, except that it searches relative to the current
# directory.
#
def require_relative(name)
scope = Rubinius::ConstantScope.of_sender
Rubinius::CodeLoader.require_relative(name, scope)
end
module_function :require_relative
def lambda
env = nil
Rubinius.asm do
push_block
# assign a pushed block to the above local variable "env"
# Note that "env" is indexed at 0.
set_local 0
end
raise ArgumentError, "block required" unless env
prc = Proc.__from_block__(env)
# Make a proc lambda only when passed an actual block (ie, not using the
# "&block" notation), otherwise don't modify it at all.
prc.lambda_style! if env.is_a?(Rubinius::BlockEnvironment)
return prc
end
module_function :lambda
def proc(&prc)
raise ArgumentError, "block required" unless prc
return prc
end
module_function :proc
def String(obj)
return obj if obj.kind_of? String
unless obj.respond_to?(:to_s)
raise TypeError, "can't convert #{obj.class} into String"
end
begin
str = obj.to_s
rescue NoMethodError
raise TypeError, "can't convert #{obj.class} into String"
end
unless str.kind_of? String
raise TypeError, "#to_s did not return a String"
end
return str
end
module_function :String
def Array(obj)
ary = Rubinius::Type.check_convert_type obj, Array, :to_ary
return ary if ary
if obj.respond_to?(:to_a) && array = Rubinius::Type.check_convert_type(obj, Array, :to_a)
array
else
[obj]
end
end
module_function :Array
def =~(other)
nil
end
def Float(obj)
raise TypeError, "can't convert nil into Float" if obj.nil?
case obj
when Float
obj
when String
Rubinius::Type.coerce_to_float(obj, true, false)
else
Rubinius::Type.coerce_to(obj, Float, :to_f)
end
end
module_function :Float
def Complex(*args)
Complex.send :convert, *args
end
module_function :Complex
def Rational(a, b = 1)
if a.kind_of?(Rational) && b == 1
a
else
Rational.send :convert, a, b
end
end
module_function :Rational
# obj <=> other -> 0 or nil
def <=>(other)
self == other ? 0 : nil
end
def initialize_dup(other)
initialize_copy(other)
end
def initialize_clone(other)
initialize_copy(other)
end
end