2 ***** BEGIN LICENSE BLOCK *****
3 * Version: CPL 1.0/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Common Public
6 * License Version 1.0 (the "License"); you may not use this file
7 * except in compliance with the License. You may obtain a copy of
8 * the License at http://www.eclipse.org/legal/cpl-v10.html
10 * Software distributed under the License is distributed on an "AS
11 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
12 * implied. See the License for the specific language governing
13 * rights and limitations under the License.
15 * Copyright (C) 2001 Chad Fowler <chadfowler@chadfowler.com>
16 * Copyright (C) 2001 Alan Moore <alan_moore@gmx.net>
17 * Copyright (C) 2001-2002 Benoit Cerrina <b.cerrina@wanadoo.fr>
18 * Copyright (C) 2001-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
19 * Copyright (C) 2002-2006 Thomas E Enebo <enebo@acm.org>
20 * Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
21 * Copyright (C) 2004-2005 Charles O Nutter <headius@headius.com>
22 * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
23 * Copyright (C) 2005 Kiel Hodges <jruby-devel@selfsosoft.com>
24 * Copyright (C) 2006 Evan Buswell <evan@heron.sytes.net>
25 * Copyright (C) 2006 Ola Bini <ola@ologix.com>
26 * Copyright (C) 2006 Michael Studman <codehaus@michaelstudman.com>
27 * Copyright (C) 2006 Miguel Covarrubias <mlcovarrubias@gmail.com>
28 * Copyright (C) 2007 Nick Sieger <nicksieger@gmail.com>
30 * Alternatively, the contents of this file may be used under the terms of
31 * either of the GNU General Public License Version 2 or later (the "GPL"),
32 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
33 * in which case the provisions of the GPL or the LGPL are applicable instead
34 * of those above. If you wish to allow use of your version of this file only
35 * under the terms of either the GPL or the LGPL, and not to allow others to
36 * use your version of this file under the terms of the CPL, indicate your
37 * decision by deleting the provisions above and replace them with the notice
38 * and other provisions required by the GPL or the LGPL. If you do not delete
39 * the provisions above, a recipient may use your version of this file under
40 * the terms of any one of the CPL, the GPL or the LGPL.
41 ***** END LICENSE BLOCK *****/
44 import java
.io
.ByteArrayOutputStream
;
45 import java
.math
.BigInteger
;
46 import java
.util
.ArrayList
;
47 import static org
.jruby
.anno
.FrameField
.*;
48 import org
.jruby
.anno
.JRubyMethod
;
49 import org
.jruby
.anno
.JRubyModule
;
51 import org
.jruby
.ast
.util
.ArgsUtil
;
52 import org
.jruby
.common
.IRubyWarnings
.ID
;
53 import org
.jruby
.evaluator
.ASTInterpreter
;
54 import org
.jruby
.exceptions
.JumpException
;
55 import org
.jruby
.exceptions
.MainExitException
;
56 import org
.jruby
.exceptions
.RaiseException
;
57 import org
.jruby
.internal
.runtime
.JumpTarget
;
58 import org
.jruby
.javasupport
.util
.RuntimeHelpers
;
59 import org
.jruby
.runtime
.Block
;
60 import org
.jruby
.runtime
.CallType
;
61 import org
.jruby
.runtime
.Frame
;
62 import org
.jruby
.runtime
.MethodIndex
;
63 import org
.jruby
.runtime
.ThreadContext
;
64 import org
.jruby
.runtime
.Visibility
;
65 import static org
.jruby
.runtime
.Visibility
.*;
66 import org
.jruby
.runtime
.builtin
.IRubyObject
;
67 import org
.jruby
.runtime
.load
.IAutoloadMethod
;
68 import org
.jruby
.runtime
.load
.LoadService
;
69 import org
.jruby
.util
.IdUtil
;
70 import org
.jruby
.util
.ShellLauncher
;
71 import org
.jruby
.util
.TypeConverter
;
74 * Note: For CVS history, see KernelModule.java.
76 @JRubyModule(name
="Kernel")
77 public class RubyKernel
{
78 public final static Class
<?
> IRUBY_OBJECT
= IRubyObject
.class;
80 public static RubyModule
createKernelModule(Ruby runtime
) {
81 RubyModule module
= runtime
.defineModule("Kernel");
82 runtime
.setKernel(module
);
84 module
.defineAnnotatedMethods(RubyKernel
.class);
85 module
.defineAnnotatedMethods(RubyObject
.class);
87 runtime
.setRespondToMethod(module
.searchMethod("respond_to?"));
89 module
.setFlag(RubyObject
.USER7_F
, false); //Kernel is the only Module that doesn't need an implementor
94 @JRubyMethod(name
= "at_exit", frame
= true, module
= true, visibility
= PRIVATE
)
95 public static IRubyObject
at_exit(ThreadContext context
, IRubyObject recv
, Block block
) {
96 return context
.getRuntime().pushExitBlock(context
.getRuntime().newProc(Block
.Type
.PROC
, block
));
99 @JRubyMethod(name
= "autoload?", required
= 1, module
= true, visibility
= PRIVATE
)
100 public static IRubyObject
autoload_p(ThreadContext context
, final IRubyObject recv
, IRubyObject symbol
) {
101 Ruby runtime
= context
.getRuntime();
102 RubyModule module
= recv
instanceof RubyModule ?
(RubyModule
) recv
: runtime
.getObject();
103 String name
= module
.getName() + "::" + symbol
.asJavaString();
105 IAutoloadMethod autoloadMethod
= runtime
.getLoadService().autoloadFor(name
);
106 if (autoloadMethod
== null) return runtime
.getNil();
108 return runtime
.newString(autoloadMethod
.file());
111 @JRubyMethod(name
= "autoload", required
= 2, frame
= true, module
= true, visibility
= PRIVATE
)
112 public static IRubyObject
autoload(final IRubyObject recv
, IRubyObject symbol
, final IRubyObject file
) {
113 Ruby runtime
= recv
.getRuntime();
114 final LoadService loadService
= runtime
.getLoadService();
115 String nonInternedName
= symbol
.asJavaString();
117 if (!IdUtil
.isValidConstantName(nonInternedName
)) {
118 throw runtime
.newNameError("autoload must be constant name", nonInternedName
);
121 RubyString fileString
= file
.convertToString();
123 if (fileString
.isEmpty()) {
124 throw runtime
.newArgumentError("empty file name");
127 final String baseName
= symbol
.asJavaString().intern(); // interned, OK for "fast" methods
128 final RubyModule module
= recv
instanceof RubyModule ?
(RubyModule
) recv
: runtime
.getObject();
129 String nm
= module
.getName() + "::" + baseName
;
131 IRubyObject existingValue
= module
.fastFetchConstant(baseName
);
132 if (existingValue
!= null && existingValue
!= RubyObject
.UNDEF
) return runtime
.getNil();
134 module
.fastStoreConstant(baseName
, RubyObject
.UNDEF
);
136 loadService
.addAutoload(nm
, new IAutoloadMethod() {
137 public String
file() {
138 return file
.toString();
141 * @see org.jruby.runtime.load.IAutoloadMethod#load(Ruby, String)
143 public IRubyObject
load(Ruby runtime
, String name
) {
144 boolean required
= loadService
.require(file());
146 // File to be loaded by autoload has already been or is being loaded.
147 if (!required
) return null;
149 return module
.fastGetConstant(baseName
);
152 return runtime
.getNil();
155 @JRubyMethod(name
= "method_missing", rest
= true, frame
= true, module
= true, visibility
= PRIVATE
)
156 public static IRubyObject
method_missing(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
, Block block
) {
157 Ruby runtime
= context
.getRuntime();
159 if (args
.length
== 0 || !(args
[0] instanceof RubySymbol
)) throw runtime
.newArgumentError("no id given");
161 Visibility lastVis
= context
.getLastVisibility();
162 CallType lastCallType
= context
.getLastCallType();
164 // create a lightweight thunk
165 IRubyObject msg
= new RubyNameError
.RubyNameErrorMessage(runtime
,
170 final IRubyObject
[]exArgs
;
172 if (lastCallType
!= CallType
.VARIABLE
) {
173 exc
= runtime
.getNoMethodError();
174 exArgs
= new IRubyObject
[]{msg
, args
[0], RubyArray
.newArrayNoCopy(runtime
, args
, 1)};
176 exc
= runtime
.getNameError();
177 exArgs
= new IRubyObject
[]{msg
, args
[0]};
180 throw new RaiseException((RubyException
)exc
.newInstance(context
, exArgs
, Block
.NULL_BLOCK
));
183 @JRubyMethod(name
= "open", required
= 1, optional
= 2, frame
= true, module
= true, visibility
= PRIVATE
)
184 public static IRubyObject
open(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
, Block block
) {
185 String arg
= args
[0].convertToString().toString();
186 Ruby runtime
= context
.getRuntime();
188 if (arg
.startsWith("|")) {
189 String command
= arg
.substring(1);
190 // exec process, create IO with process
191 return RubyIO
.popen(context
, runtime
.getIO(), new IRubyObject
[] {runtime
.newString(command
)}, block
);
194 return RubyFile
.open(context
, runtime
.getFile(), args
, block
);
197 @JRubyMethod(name
= "getc", module
= true, visibility
= PRIVATE
)
198 public static IRubyObject
getc(ThreadContext context
, IRubyObject recv
) {
199 context
.getRuntime().getWarnings().warn(ID
.DEPRECATED_METHOD
, "getc is obsolete; use STDIN.getc instead", "getc", "STDIN.getc");
200 IRubyObject defin
= context
.getRuntime().getGlobalVariables().get("$stdin");
201 return defin
.callMethod(context
, "getc");
204 @JRubyMethod(name
= "gets", optional
= 1, module
= true, visibility
= PRIVATE
)
205 public static IRubyObject
gets(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
206 return RubyArgsFile
.gets(context
, context
.getRuntime().getGlobalVariables().get("$<"), args
);
209 @JRubyMethod(name
= "abort", optional
= 1, module
= true, visibility
= PRIVATE
)
210 public static IRubyObject
abort(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
211 if(args
.length
== 1) {
212 context
.getRuntime().getGlobalVariables().get("$stderr").callMethod(context
,"puts",args
[0]);
214 throw new MainExitException(1,true);
217 @JRubyMethod(name
= "Array", required
= 1, module
= true, visibility
= PRIVATE
)
218 public static IRubyObject
new_array(ThreadContext context
, IRubyObject recv
, IRubyObject object
) {
219 IRubyObject value
= object
.checkArrayType();
222 if (object
.getMetaClass().searchMethod("to_a").getImplementationClass() != context
.getRuntime().getKernel()) {
223 value
= object
.callMethod(context
, MethodIndex
.TO_A
, "to_a");
224 if (!(value
instanceof RubyArray
)) throw context
.getRuntime().newTypeError("`to_a' did not return Array");
227 return context
.getRuntime().newArray(object
);
233 @JRubyMethod(name
= "Complex", required
= 0, optional
= 2, module
= true, visibility
= PRIVATE
, compat
= CompatVersion
.RUBY1_9
)
234 public static IRubyObject
new_complex(ThreadContext context
, IRubyObject recv
, IRubyObject
[]args
) {
235 return context
.getRuntime().getComplex().callMethod(context
, "convert", args
);
238 @JRubyMethod(name
= "Rational", required
= 0, optional
= 2, module
= true, visibility
= PRIVATE
, compat
= CompatVersion
.RUBY1_9
)
239 public static IRubyObject
new_rational(ThreadContext context
, IRubyObject recv
, IRubyObject
[]args
) {
240 return context
.getRuntime().getRational().callMethod(context
, "convert", args
);
243 @JRubyMethod(name
= "Float", required
= 1, module
= true, visibility
= PRIVATE
)
244 public static IRubyObject
new_float(IRubyObject recv
, IRubyObject object
) {
245 if(object
instanceof RubyFixnum
){
246 return RubyFloat
.newFloat(object
.getRuntime(), ((RubyFixnum
)object
).getDoubleValue());
247 }else if(object
instanceof RubyFloat
){
249 }else if(object
instanceof RubyBignum
){
250 return RubyFloat
.newFloat(object
.getRuntime(), RubyBignum
.big2dbl((RubyBignum
)object
));
251 }else if(object
instanceof RubyString
){
252 if(((RubyString
)object
).getByteList().realSize
== 0){ // rb_cstr_to_dbl case
253 throw recv
.getRuntime().newArgumentError("invalid value for Float(): " + object
.inspect());
255 return RubyNumeric
.str2fnum(recv
.getRuntime(),(RubyString
)object
,true);
256 }else if(object
.isNil()){
257 throw recv
.getRuntime().newTypeError("can't convert nil into Float");
259 RubyFloat rFloat
= (RubyFloat
)TypeConverter
.convertToType(object
, recv
.getRuntime().getFloat(), MethodIndex
.TO_F
, "to_f");
260 if (Double
.isNaN(rFloat
.getDoubleValue())) throw recv
.getRuntime().newArgumentError("invalid value for Float()");
265 @JRubyMethod(name
= "Integer", required
= 1, module
= true, visibility
= PRIVATE
)
266 public static IRubyObject
new_integer(ThreadContext context
, IRubyObject recv
, IRubyObject object
) {
267 if (object
instanceof RubyFloat
) {
268 double val
= ((RubyFloat
)object
).getDoubleValue();
269 if (val
> (double) RubyFixnum
.MAX
&& val
< (double) RubyFixnum
.MIN
) {
270 return RubyNumeric
.dbl2num(context
.getRuntime(),((RubyFloat
)object
).getDoubleValue());
272 } else if (object
instanceof RubyFixnum
|| object
instanceof RubyBignum
) {
274 } else if (object
instanceof RubyString
) {
275 return RubyNumeric
.str2inum(context
.getRuntime(),(RubyString
)object
,0,true);
278 IRubyObject tmp
= TypeConverter
.convertToType(object
, context
.getRuntime().getInteger(), MethodIndex
.TO_INT
, "to_int", false);
279 if (tmp
.isNil()) return object
.convertToInteger(MethodIndex
.TO_I
, "to_i");
283 @JRubyMethod(name
= "String", required
= 1, module
= true, visibility
= PRIVATE
)
284 public static IRubyObject
new_string(ThreadContext context
, IRubyObject recv
, IRubyObject object
) {
285 return TypeConverter
.convertToType(object
, context
.getRuntime().getString(), MethodIndex
.TO_S
, "to_s");
288 @JRubyMethod(name
= "p", rest
= true, module
= true, visibility
= PRIVATE
)
289 public static IRubyObject
p(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
290 Ruby runtime
= context
.getRuntime();
291 IRubyObject defout
= runtime
.getGlobalVariables().get("$>");
293 for (int i
= 0; i
< args
.length
; i
++) {
294 if (args
[i
] != null) {
295 defout
.callMethod(context
, "write", RubyObject
.inspect(context
, args
[i
]));
296 defout
.callMethod(context
, "write", runtime
.newString("\n"));
300 if (defout
instanceof RubyFile
) {
301 ((RubyFile
)defout
).flush();
304 return context
.getRuntime().getNil();
309 @JRubyMethod(name
= "putc", required
= 1, module
= true, visibility
= PRIVATE
)
310 public static IRubyObject
putc(ThreadContext context
, IRubyObject recv
, IRubyObject ch
) {
311 IRubyObject defout
= context
.getRuntime().getGlobalVariables().get("$>");
312 return defout
.callMethod(context
, "putc", ch
);
315 @JRubyMethod(name
= "puts", rest
= true, module
= true, visibility
= PRIVATE
)
316 public static IRubyObject
puts(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
317 IRubyObject defout
= context
.getRuntime().getGlobalVariables().get("$>");
319 defout
.callMethod(context
, "puts", args
);
321 return context
.getRuntime().getNil();
324 @JRubyMethod(name
= "print", rest
= true, module
= true, visibility
= PRIVATE
)
325 public static IRubyObject
print(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
326 IRubyObject defout
= context
.getRuntime().getGlobalVariables().get("$>");
328 defout
.callMethod(context
, "print", args
);
330 return context
.getRuntime().getNil();
333 @JRubyMethod(name
= "printf", rest
= true, module
= true, visibility
= PRIVATE
)
334 public static IRubyObject
printf(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
335 if (args
.length
!= 0) {
336 IRubyObject defout
= context
.getRuntime().getGlobalVariables().get("$>");
338 if (!(args
[0] instanceof RubyString
)) {
340 args
= ArgsUtil
.popArray(args
);
343 defout
.callMethod(context
, "write", RubyKernel
.sprintf(recv
, args
));
346 return context
.getRuntime().getNil();
349 @JRubyMethod(name
= "readline", optional
= 1, module
= true, visibility
= PRIVATE
)
350 public static IRubyObject
readline(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
351 IRubyObject line
= gets(context
, recv
, args
);
353 if (line
.isNil()) throw context
.getRuntime().newEOFError();
358 @JRubyMethod(name
= "readlines", optional
= 1, module
= true, visibility
= PRIVATE
)
359 public static RubyArray
readlines(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
360 return RubyArgsFile
.readlines(context
, context
.getRuntime().getGlobalVariables().get("$<"), args
);
363 /** Returns value of $_.
365 * @throws TypeError if $_ is not a String or nil.
366 * @return value of $_ as String.
368 private static RubyString
getLastlineString(ThreadContext context
, Ruby runtime
) {
369 IRubyObject line
= context
.getPreviousFrame().getLastLine();
372 throw runtime
.newTypeError("$_ value need to be String (nil given).");
373 } else if (!(line
instanceof RubyString
)) {
374 throw runtime
.newTypeError("$_ value need to be String (" + line
.getMetaClass().getName() + " given).");
376 return (RubyString
) line
;
381 * Variable-arity version for compatibility. Not bound to Ruby.
382 * @deprecated Use the one or two-arg versions.
384 public static IRubyObject
sub_bang(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
, Block block
) {
385 return getLastlineString(context
, context
.getRuntime()).sub_bang(context
, args
, block
);
388 @JRubyMethod(name
= "sub!", frame
= true, module
= true, visibility
= PRIVATE
, reads
= LASTLINE
)
389 public static IRubyObject
sub_bang(ThreadContext context
, IRubyObject recv
, IRubyObject arg0
, Block block
) {
390 return getLastlineString(context
, context
.getRuntime()).sub_bang(context
, arg0
, block
);
393 @JRubyMethod(name
= "sub!", frame
= true, module
= true, visibility
= PRIVATE
, reads
= LASTLINE
)
394 public static IRubyObject
sub_bang(ThreadContext context
, IRubyObject recv
, IRubyObject arg0
, IRubyObject arg1
, Block block
) {
395 return getLastlineString(context
, context
.getRuntime()).sub_bang(context
, arg0
, arg1
, block
);
399 * Variable-arity version for compatibility. Not bound to Ruby.
400 * @deprecated Use the one or two-arg versions.
402 public static IRubyObject
sub(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
, Block block
) {
403 RubyString str
= (RubyString
) getLastlineString(context
, context
.getRuntime()).dup();
405 if (!str
.sub_bang(context
, args
, block
).isNil()) {
406 context
.getPreviousFrame().setLastLine(str
);
412 @JRubyMethod(name
= "sub", frame
= true, module
= true, visibility
= PRIVATE
, reads
= LASTLINE
, writes
= LASTLINE
)
413 public static IRubyObject
sub(ThreadContext context
, IRubyObject recv
, IRubyObject arg0
, Block block
) {
414 RubyString str
= (RubyString
) getLastlineString(context
, context
.getRuntime()).dup();
416 if (!str
.sub_bang(context
, arg0
, block
).isNil()) {
417 context
.getPreviousFrame().setLastLine(str
);
423 @JRubyMethod(name
= "sub", frame
= true, module
= true, visibility
= PRIVATE
, reads
= LASTLINE
, writes
= LASTLINE
)
424 public static IRubyObject
sub(ThreadContext context
, IRubyObject recv
, IRubyObject arg0
, IRubyObject arg1
, Block block
) {
425 RubyString str
= (RubyString
) getLastlineString(context
, context
.getRuntime()).dup();
427 if (!str
.sub_bang(context
, arg0
, arg1
, block
).isNil()) {
428 context
.getPreviousFrame().setLastLine(str
);
435 * Variable-arity version for compatibility. Not bound to Ruby.
436 * @deprecated Use the one or two-arg versions.
438 public static IRubyObject
gsub_bang(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
, Block block
) {
439 return getLastlineString(context
, context
.getRuntime()).gsub_bang(context
, args
, block
);
442 @JRubyMethod(name
= "gsub!", frame
= true, module
= true, visibility
= PRIVATE
, reads
= LASTLINE
, writes
= LASTLINE
)
443 public static IRubyObject
gsub_bang(ThreadContext context
, IRubyObject recv
, IRubyObject arg0
, Block block
) {
444 return getLastlineString(context
, context
.getRuntime()).gsub_bang(context
, arg0
, block
);
447 @JRubyMethod(name
= "gsub!", frame
= true, module
= true, visibility
= PRIVATE
, reads
= LASTLINE
, writes
= LASTLINE
)
448 public static IRubyObject
gsub_bang(ThreadContext context
, IRubyObject recv
, IRubyObject arg0
, IRubyObject arg1
, Block block
) {
449 return getLastlineString(context
, context
.getRuntime()).gsub_bang(context
, arg0
, arg1
, block
);
453 * Variable-arity version for compatibility. Not bound to Ruby.
454 * @deprecated Use the one or two-arg versions.
456 public static IRubyObject
gsub(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
, Block block
) {
457 RubyString str
= (RubyString
) getLastlineString(context
, context
.getRuntime()).dup();
459 if (!str
.gsub_bang(context
, args
, block
).isNil()) {
460 context
.getPreviousFrame().setLastLine(str
);
466 @JRubyMethod(name
= "gsub", frame
= true, module
= true, visibility
= PRIVATE
, reads
= LASTLINE
, writes
= LASTLINE
)
467 public static IRubyObject
gsub(ThreadContext context
, IRubyObject recv
, IRubyObject arg0
, Block block
) {
468 RubyString str
= (RubyString
) getLastlineString(context
, context
.getRuntime()).dup();
470 if (!str
.gsub_bang(context
, arg0
, block
).isNil()) {
471 context
.getPreviousFrame().setLastLine(str
);
477 @JRubyMethod(name
= "gsub", frame
= true, module
= true, visibility
= PRIVATE
, reads
= LASTLINE
, writes
= LASTLINE
)
478 public static IRubyObject
gsub(ThreadContext context
, IRubyObject recv
, IRubyObject arg0
, IRubyObject arg1
, Block block
) {
479 RubyString str
= (RubyString
) getLastlineString(context
, context
.getRuntime()).dup();
481 if (!str
.gsub_bang(context
, arg0
, arg1
, block
).isNil()) {
482 context
.getPreviousFrame().setLastLine(str
);
488 @JRubyMethod(name
= "chop!", frame
= true, module
= true, visibility
= PRIVATE
, reads
= LASTLINE
, writes
= LASTLINE
)
489 public static IRubyObject
chop_bang(ThreadContext context
, IRubyObject recv
, Block block
) {
490 return getLastlineString(context
, context
.getRuntime()).chop_bang();
493 @JRubyMethod(name
= "chop", frame
= true, module
= true, visibility
= PRIVATE
, reads
= LASTLINE
, writes
= LASTLINE
)
494 public static IRubyObject
chop(ThreadContext context
, IRubyObject recv
, Block block
) {
495 RubyString str
= getLastlineString(context
, context
.getRuntime());
497 if (str
.getByteList().realSize
> 0) {
498 str
= (RubyString
) str
.dup();
500 context
.getPreviousFrame().setLastLine(str
);
507 * Variable-arity version for compatibility. Not bound to Ruby.
508 * @deprecated Use the zero or one-arg versions.
510 public static IRubyObject
chomp_bang(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
, Block block
) {
511 return getLastlineString(context
, context
.getRuntime()).chomp_bang(args
);
514 @JRubyMethod(name
= "chomp!", frame
= true, module
= true, visibility
= PRIVATE
, reads
= LASTLINE
, writes
= LASTLINE
)
515 public static IRubyObject
chomp_bang(ThreadContext context
, IRubyObject recv
) {
516 return getLastlineString(context
, context
.getRuntime()).chomp_bang();
519 @JRubyMethod(name
= "chomp!", frame
= true, module
= true, visibility
= PRIVATE
, reads
= LASTLINE
, writes
= LASTLINE
)
520 public static IRubyObject
chomp_bang(ThreadContext context
, IRubyObject recv
, IRubyObject arg0
) {
521 return getLastlineString(context
, context
.getRuntime()).chomp_bang(arg0
);
525 * Variable-arity version for compatibility. Not bound to Ruby.
526 * @deprecated Use the zero or one-arg versions.
528 public static IRubyObject
chomp(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
, Block block
) {
529 RubyString str
= getLastlineString(context
, context
.getRuntime());
530 RubyString dup
= (RubyString
) str
.dup();
532 if (dup
.chomp_bang(args
).isNil()) {
536 context
.getPreviousFrame().setLastLine(dup
);
540 @JRubyMethod(name
= "chomp", frame
= true, module
= true, visibility
= PRIVATE
, reads
= LASTLINE
, writes
= LASTLINE
)
541 public static IRubyObject
chomp(ThreadContext context
, IRubyObject recv
) {
542 RubyString str
= getLastlineString(context
, context
.getRuntime());
543 RubyString dup
= (RubyString
) str
.dup();
545 if (dup
.chomp_bang().isNil()) {
549 context
.getPreviousFrame().setLastLine(dup
);
553 @JRubyMethod(name
= "chomp", frame
= true, module
= true, visibility
= PRIVATE
, reads
= LASTLINE
, writes
= LASTLINE
)
554 public static IRubyObject
chomp(ThreadContext context
, IRubyObject recv
, IRubyObject arg0
) {
555 RubyString str
= getLastlineString(context
, context
.getRuntime());
556 RubyString dup
= (RubyString
) str
.dup();
558 if (dup
.chomp_bang(arg0
).isNil()) {
562 context
.getPreviousFrame().setLastLine(dup
);
567 * Variable arity version for compatibility. Not bound to a Ruby method.
569 * @param context The thread context for the current thread
570 * @param recv The receiver of the method (usually a class that has included Kernel)
572 * @deprecated Use the versions with zero, one, or two args.
574 public static IRubyObject
split(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
575 return getLastlineString(context
, context
.getRuntime()).split(context
, args
);
578 @JRubyMethod(name
= "split", frame
= true, module
= true, visibility
= PRIVATE
, reads
= LASTLINE
, writes
= {LASTLINE
, BACKREF
})
579 public static IRubyObject
split(ThreadContext context
, IRubyObject recv
) {
580 return getLastlineString(context
, context
.getRuntime()).split(context
);
583 @JRubyMethod(name
= "split", frame
= true, module
= true, visibility
= PRIVATE
, reads
= LASTLINE
, writes
= {LASTLINE
, BACKREF
})
584 public static IRubyObject
split(ThreadContext context
, IRubyObject recv
, IRubyObject arg0
) {
585 return getLastlineString(context
, context
.getRuntime()).split(context
, arg0
);
588 @JRubyMethod(name
= "split", frame
= true, module
= true, visibility
= PRIVATE
, reads
= LASTLINE
, writes
= {LASTLINE
, BACKREF
})
589 public static IRubyObject
split(ThreadContext context
, IRubyObject recv
, IRubyObject arg0
, IRubyObject arg1
) {
590 return getLastlineString(context
, context
.getRuntime()).split(context
, arg0
, arg1
);
593 @JRubyMethod(name
= "scan", required
= 1, frame
= true, module
= true, visibility
= PRIVATE
, reads
= {LASTLINE
, BACKREF
}, writes
= {LASTLINE
, BACKREF
})
594 public static IRubyObject
scan(ThreadContext context
, IRubyObject recv
, IRubyObject pattern
, Block block
) {
595 return getLastlineString(context
, context
.getRuntime()).scan(context
, pattern
, block
);
598 @JRubyMethod(name
= "select", required
= 1, optional
= 3, module
= true, visibility
= PRIVATE
)
599 public static IRubyObject
select(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
600 return RubyIO
.select_static(context
, context
.getRuntime(), args
);
603 @JRubyMethod(name
= "sleep", optional
= 1, module
= true, visibility
= PRIVATE
)
604 public static IRubyObject
sleep(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
607 if (args
.length
== 0) {
608 // Zero sleeps forever
611 if (!(args
[0] instanceof RubyNumeric
)) {
612 throw context
.getRuntime().newTypeError("can't convert " + args
[0].getMetaClass().getName() + "into time interval");
614 milliseconds
= (long) (args
[0].convertToFloat().getDoubleValue() * 1000);
615 if (milliseconds
< 0) {
616 throw context
.getRuntime().newArgumentError("time interval must be positive");
617 } else if (milliseconds
== 0) {
618 // Explicit zero in MRI returns immediately
619 return context
.getRuntime().newFixnum(0);
622 long startTime
= System
.currentTimeMillis();
624 RubyThread rubyThread
= context
.getThread();
627 long loopStartTime
= System
.currentTimeMillis();
629 rubyThread
.sleep(milliseconds
);
630 } catch (InterruptedException iExcptn
) {
632 milliseconds
-= (System
.currentTimeMillis() - loopStartTime
);
633 } while (milliseconds
> 0);
635 return context
.getRuntime().newFixnum(Math
.round((System
.currentTimeMillis() - startTime
) / 1000.0));
638 // FIXME: Add at_exit and finalizers to exit, then make exit_bang not call those.
639 @JRubyMethod(name
= "exit", optional
= 1, module
= true, visibility
= PRIVATE
)
640 public static IRubyObject
exit(IRubyObject recv
, IRubyObject
[] args
) {
641 exit(recv
.getRuntime(), args
, false);
642 return recv
.getRuntime().getNil(); // not reached
645 @JRubyMethod(name
= "exit!", optional
= 1, module
= true, visibility
= PRIVATE
)
646 public static IRubyObject
exit_bang(IRubyObject recv
, IRubyObject
[] args
) {
647 exit(recv
.getRuntime(), args
, true);
648 return recv
.getRuntime().getNil(); // not reached
651 private static void exit(Ruby runtime
, IRubyObject
[] args
, boolean hard
) {
655 if (args
.length
> 0) {
656 RubyObject argument
= (RubyObject
)args
[0];
657 if (argument
instanceof RubyFixnum
) {
658 status
= RubyNumeric
.fix2int(argument
);
660 status
= argument
.isFalse() ?
1 : 0;
665 throw new MainExitException(status
, true);
667 throw runtime
.newSystemExit(status
);
672 /** Returns an Array with the names of all global variables.
675 @JRubyMethod(name
= "global_variables", module
= true, visibility
= PRIVATE
)
676 public static RubyArray
global_variables(ThreadContext context
, IRubyObject recv
) {
677 Ruby runtime
= context
.getRuntime();
678 RubyArray globalVariables
= runtime
.newArray();
680 for (String globalVariableName
: runtime
.getGlobalVariables().getNames()) {
681 globalVariables
.append(runtime
.newString(globalVariableName
));
684 return globalVariables
;
687 /** Returns an Array with the names of all local variables.
690 @JRubyMethod(name
= "local_variables", module
= true, visibility
= PRIVATE
)
691 public static RubyArray
local_variables(ThreadContext context
, IRubyObject recv
) {
692 final Ruby runtime
= context
.getRuntime();
693 RubyArray localVariables
= runtime
.newArray();
695 for (String name
: context
.getCurrentScope().getAllNamesInScope()) {
696 if (IdUtil
.isLocal(name
)) localVariables
.append(runtime
.newString(name
));
699 return localVariables
;
702 @JRubyMethod(name
= "binding", frame
= true, module
= true, visibility
= PRIVATE
)
703 public static RubyBinding
binding(ThreadContext context
, IRubyObject recv
, Block block
) {
704 return RubyBinding
.newBindingForEval(context
);
707 @JRubyMethod(name
= {"block_given?", "iterator?"}, frame
= true, module
= true, visibility
= PRIVATE
)
708 public static RubyBoolean
block_given_p(ThreadContext context
, IRubyObject recv
, Block block
) {
709 return context
.getRuntime().newBoolean(context
.getPreviousFrame().getBlock().isGiven());
714 public static IRubyObject
sprintf(IRubyObject recv
, IRubyObject
[] args
) {
715 return sprintf(recv
.getRuntime().getCurrentContext(), recv
, args
);
718 @JRubyMethod(name
= {"sprintf", "format"}, required
= 1, rest
= true, module
= true, visibility
= PRIVATE
)
719 public static IRubyObject
sprintf(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
720 if (args
.length
== 0) {
721 throw context
.getRuntime().newArgumentError("sprintf must have at least one argument");
724 RubyString str
= RubyString
.stringValue(args
[0]);
726 RubyArray newArgs
= context
.getRuntime().newArrayNoCopy(args
);
729 return str
.op_format(context
, newArgs
);
732 @JRubyMethod(name
= {"raise", "fail"}, optional
= 3, frame
= true, module
= true, visibility
= PRIVATE
)
733 public static IRubyObject
raise(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
, Block block
) {
734 // FIXME: Pass block down?
735 Ruby runtime
= context
.getRuntime();
737 if (args
.length
== 0) {
738 IRubyObject lastException
= runtime
.getGlobalVariables().get("$!");
739 if (lastException
.isNil()) {
740 throw new RaiseException(runtime
, runtime
.getRuntimeError(), "", false);
742 throw new RaiseException((RubyException
) lastException
);
745 IRubyObject exception
;
747 if (args
.length
== 1) {
748 if (args
[0] instanceof RubyString
) {
749 throw new RaiseException((RubyException
)runtime
.getRuntimeError().newInstance(context
, args
, block
));
752 if (!args
[0].respondsTo("exception")) {
753 throw runtime
.newTypeError("exception class/object expected");
755 exception
= args
[0].callMethod(context
, "exception");
757 if (!args
[0].respondsTo("exception")) {
758 throw runtime
.newTypeError("exception class/object expected");
761 exception
= args
[0].callMethod(context
, "exception", args
[1]);
764 if (!runtime
.fastGetClass("Exception").isInstance(exception
)) {
765 throw runtime
.newTypeError("exception object expected");
768 if (args
.length
== 3) {
769 ((RubyException
) exception
).set_backtrace(args
[2]);
772 if (runtime
.getDebug().isTrue()) {
773 printExceptionSummary(context
, runtime
, (RubyException
) exception
);
776 throw new RaiseException((RubyException
) exception
);
779 private static void printExceptionSummary(ThreadContext context
, Ruby runtime
, RubyException rEx
) {
780 Frame currentFrame
= context
.getCurrentFrame();
782 String msg
= String
.format("Exception `%s' at %s:%s - %s\n",
784 currentFrame
.getFile(), currentFrame
.getLine() + 1,
787 IRubyObject errorStream
= runtime
.getGlobalVariables().get("$stderr");
788 errorStream
.callMethod(context
, "write", runtime
.newString(msg
));
793 * MRI allows to require ever .rb files or ruby extension dll (.so or .dll depending on system).
794 * we allow requiring either .rb files or jars.
795 * @param recv ruby object used to call require (any object will do and it won't be used anyway).
796 * @param name the name of the file to require
798 @JRubyMethod(name
= "require", required
= 1, frame
= true, module
= true, visibility
= PRIVATE
)
799 public static IRubyObject
require(IRubyObject recv
, IRubyObject name
, Block block
) {
800 Ruby runtime
= recv
.getRuntime();
802 if (runtime
.getLoadService().require(name
.convertToString().toString())) {
803 return runtime
.getTrue();
805 return runtime
.getFalse();
808 @JRubyMethod(name
= "load", required
= 1, optional
= 1, frame
= true, module
= true, visibility
= PRIVATE
)
809 public static IRubyObject
load(IRubyObject recv
, IRubyObject
[] args
, Block block
) {
810 Ruby runtime
= recv
.getRuntime();
811 RubyString file
= args
[0].convertToString();
812 boolean wrap
= args
.length
== 2 ? args
[1].isTrue() : false;
814 runtime
.getLoadService().load(file
.getByteList().toString(), wrap
);
816 return runtime
.getTrue();
819 @JRubyMethod(name
= "eval", required
= 1, optional
= 3, frame
= true, module
= true, visibility
= PRIVATE
)
820 public static IRubyObject
eval(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
, Block block
) {
821 Ruby runtime
= context
.getRuntime();
824 RubyString src
= args
[0].convertToString();
825 runtime
.checkSafeString(src
);
827 IRubyObject scope
= args
.length
> 1 && !args
[1].isNil() ? args
[1] : null;
829 if (args
.length
> 2) {
830 file
= args
[2].convertToString().toString();
831 } else if (scope
== null) {
837 if (args
.length
> 3) {
838 line
= (int) args
[3].convertToInteger().getLongValue();
839 } else if (scope
== null) {
844 if (scope
== null) scope
= RubyBinding
.newBindingForEval(context
);
846 return ASTInterpreter
.evalWithBinding(context
, src
, scope
, file
, line
);
849 @JRubyMethod(name
= "callcc", frame
= true, module
= true, visibility
= PRIVATE
)
850 public static IRubyObject
callcc(ThreadContext context
, IRubyObject recv
, Block block
) {
851 Ruby runtime
= context
.getRuntime();
852 runtime
.getWarnings().warn(ID
.EMPTY_IMPLEMENTATION
, "Kernel#callcc: Continuations are not implemented in JRuby and will not work", "Kernel#callcc");
853 IRubyObject cc
= runtime
.getContinuation().callMethod(context
, "new");
854 cc
.dataWrapStruct(block
);
855 return block
.yield(context
, cc
);
858 @JRubyMethod(name
= "caller", optional
= 1, frame
= true, module
= true, visibility
= PRIVATE
)
859 public static IRubyObject
caller(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
, Block block
) {
860 int level
= args
.length
> 0 ? RubyNumeric
.fix2int(args
[0]) : 1;
863 throw context
.getRuntime().newArgumentError("negative level(" + level
+ ')');
866 return context
.createCallerBacktrace(context
.getRuntime(), level
);
869 @JRubyMethod(name
= "catch", required
= 1, frame
= true, module
= true, visibility
= PRIVATE
)
870 public static IRubyObject
rbCatch(ThreadContext context
, IRubyObject recv
, IRubyObject tag
, Block block
) {
871 CatchTarget target
= new CatchTarget(tag
.asJavaString());
873 context
.pushCatch(target
);
874 return block
.yield(context
, tag
);
875 } catch (JumpException
.ThrowJump tj
) {
876 if (tj
.getTarget() == target
) return (IRubyObject
) tj
.getValue();
884 public static class CatchTarget
implements JumpTarget
{
885 private final String tag
;
886 public CatchTarget(String tag
) { this.tag
= tag
; }
887 public String
getTag() { return tag
; }
890 @JRubyMethod(name
= "throw", required
= 1, frame
= true, optional
= 1, module
= true, visibility
= PRIVATE
)
891 public static IRubyObject
rbThrow(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
, Block block
) {
892 Ruby runtime
= context
.getRuntime();
894 String tag
= args
[0].asJavaString();
895 CatchTarget
[] catches
= context
.getActiveCatches();
897 String message
= "uncaught throw `" + tag
+ "'";
899 // Ordering of array traversal not important, just intuitive
900 for (int i
= catches
.length
- 1 ; i
>= 0 ; i
--) {
901 if (tag
.equals(catches
[i
].getTag())) {
902 //Catch active, throw for catch to handle
903 throw new JumpException
.ThrowJump(catches
[i
], args
.length
> 1 ? args
[1] : runtime
.getNil());
907 // No catch active for this throw
908 RubyThread currentThread
= context
.getThread();
909 if (currentThread
== runtime
.getThreadService().getMainThread()) {
910 throw runtime
.newNameError(message
, tag
);
912 throw runtime
.newThreadError(message
+ " in thread 0x" + Integer
.toHexString(RubyInteger
.fix2int(currentThread
.id())));
916 @JRubyMethod(name
= "trap", required
= 1, frame
= true, optional
= 1, module
= true, visibility
= PRIVATE
)
917 public static IRubyObject
trap(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
, Block block
) {
918 context
.getRuntime().getLoadService().require("jsignal");
919 return RuntimeHelpers
.invoke(context
, recv
, "__jtrap", args
, block
);
922 @JRubyMethod(name
= "warn", required
= 1, module
= true, visibility
= PRIVATE
)
923 public static IRubyObject
warn(ThreadContext context
, IRubyObject recv
, IRubyObject message
) {
924 Ruby runtime
= context
.getRuntime();
926 if (!runtime
.getVerbose().isNil()) {
927 IRubyObject out
= runtime
.getGlobalVariables().get("$stderr");
928 out
.callMethod(context
, "puts", new IRubyObject
[] { message
});
930 return runtime
.getNil();
933 @JRubyMethod(name
= "set_trace_func", required
= 1, frame
= true, module
= true, visibility
= PRIVATE
)
934 public static IRubyObject
set_trace_func(ThreadContext context
, IRubyObject recv
, IRubyObject trace_func
, Block block
) {
935 if (trace_func
.isNil()) {
936 context
.getRuntime().setTraceFunction(null);
937 } else if (!(trace_func
instanceof RubyProc
)) {
938 throw context
.getRuntime().newTypeError("trace_func needs to be Proc.");
940 context
.getRuntime().setTraceFunction((RubyProc
) trace_func
);
945 @JRubyMethod(name
= "trace_var", required
= 1, optional
= 1, frame
= true, module
= true, visibility
= PRIVATE
)
946 public static IRubyObject
trace_var(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
, Block block
) {
947 if (args
.length
== 0) throw context
.getRuntime().newArgumentError(0, 1);
948 RubyProc proc
= null;
949 String var
= args
.length
> 1 ? args
[0].toString() : null;
950 // ignore if it's not a global var
951 if (var
.charAt(0) != '$') return context
.getRuntime().getNil();
952 if (args
.length
== 1) proc
= RubyProc
.newProc(context
.getRuntime(), block
, Block
.Type
.PROC
);
953 if (args
.length
== 2) {
954 proc
= (RubyProc
)TypeConverter
.convertToType(args
[1], context
.getRuntime().getProc(), 0, "to_proc", true);
957 context
.getRuntime().getGlobalVariables().setTraceVar(var
, proc
);
959 return context
.getRuntime().getNil();
962 @JRubyMethod(name
= "untrace_var", required
= 1, optional
= 1, frame
= true, module
= true, visibility
= PRIVATE
)
963 public static IRubyObject
untrace_var(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
, Block block
) {
964 if (args
.length
== 0) throw context
.getRuntime().newArgumentError(0, 1);
965 String var
= args
.length
>= 1 ? args
[0].toString() : null;
967 // ignore if it's not a global var
968 if (var
.charAt(0) != '$') return context
.getRuntime().getNil();
970 if (args
.length
> 1) {
971 ArrayList
<IRubyObject
> success
= new ArrayList
<IRubyObject
>();
972 for (int i
= 1; i
< args
.length
; i
++) {
973 if (context
.getRuntime().getGlobalVariables().untraceVar(var
, args
[i
])) {
974 success
.add(args
[i
]);
977 return RubyArray
.newArray(context
.getRuntime(), success
);
979 context
.getRuntime().getGlobalVariables().untraceVar(var
);
982 return context
.getRuntime().getNil();
985 @JRubyMethod(name
= "singleton_method_added", required
= 1, frame
= true, module
= true, visibility
= PRIVATE
)
986 public static IRubyObject
singleton_method_added(ThreadContext context
, IRubyObject recv
, IRubyObject symbolId
, Block block
) {
987 return context
.getRuntime().getNil();
990 @JRubyMethod(name
= "singleton_method_removed", required
= 1, frame
= true, module
= true, visibility
= PRIVATE
)
991 public static IRubyObject
singleton_method_removed(ThreadContext context
, IRubyObject recv
, IRubyObject symbolId
, Block block
) {
992 return context
.getRuntime().getNil();
995 @JRubyMethod(name
= "singleton_method_undefined", required
= 1, frame
= true, module
= true, visibility
= PRIVATE
)
996 public static IRubyObject
singleton_method_undefined(ThreadContext context
, IRubyObject recv
, IRubyObject symbolId
, Block block
) {
997 return context
.getRuntime().getNil();
1000 @JRubyMethod(name
= {"proc", "lambda"}, frame
= true, module
= true, visibility
= PRIVATE
, compat
= CompatVersion
.RUBY1_8
)
1001 public static RubyProc
proc(ThreadContext context
, IRubyObject recv
, Block block
) {
1002 return context
.getRuntime().newProc(Block
.Type
.LAMBDA
, block
);
1006 public static RubyProc
proc(IRubyObject recv
, Block block
) {
1007 return recv
.getRuntime().newProc(Block
.Type
.LAMBDA
, block
);
1010 @JRubyMethod(name
= {"lambda"}, frame
= true, module
= true, visibility
= PRIVATE
, compat
= CompatVersion
.RUBY1_9
)
1011 public static RubyProc
lambda(ThreadContext context
, IRubyObject recv
, Block block
) {
1012 return context
.getRuntime().newProc(Block
.Type
.LAMBDA
, block
);
1015 @JRubyMethod(name
= {"proc"}, frame
= true, module
= true, visibility
= PRIVATE
, compat
= CompatVersion
.RUBY1_9
)
1016 public static RubyProc
proc_1_9(ThreadContext context
, IRubyObject recv
, Block block
) {
1017 return context
.getRuntime().newProc(Block
.Type
.PROC
, block
);
1020 @JRubyMethod(name
= "loop", frame
= true, module
= true, visibility
= PRIVATE
)
1021 public static IRubyObject
loop(ThreadContext context
, IRubyObject recv
, Block block
) {
1023 block
.yield(context
, context
.getRuntime().getNil());
1025 context
.pollThreadEvents();
1029 @JRubyMethod(name
= "test", required
= 2, optional
= 1, module
= true, visibility
= PRIVATE
)
1030 public static IRubyObject
test(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
1031 if (args
.length
== 0) throw context
.getRuntime().newArgumentError("wrong number of arguments");
1034 if (args
[0] instanceof RubyFixnum
) {
1035 cmd
= (int)((RubyFixnum
) args
[0]).getLongValue();
1036 } else if (args
[0] instanceof RubyString
&&
1037 ((RubyString
) args
[0]).getByteList().length() > 0) {
1038 // MRI behavior: use first byte of string value if len > 0
1039 cmd
= ((RubyString
) args
[0]).getByteList().charAt(0);
1041 cmd
= (int) args
[0].convertToInteger().getLongValue();
1044 // MRI behavior: raise ArgumentError for 'unknown command' before
1045 // checking number of args.
1047 case 'A': case 'b': case 'c': case 'C': case 'd': case 'e': case 'f': case 'g': case 'G':
1048 case 'k': case 'M': case 'l': case 'o': case 'O': case 'p': case 'r': case 'R': case 's':
1049 case 'S': case 'u': case 'w': case 'W': case 'x': case 'X': case 'z': case '=': case '<':
1053 throw context
.getRuntime().newArgumentError("unknown command ?" + (char) cmd
);
1056 // MRI behavior: now check arg count
1059 case '-': case '=': case '<': case '>':
1060 if (args
.length
!= 3) throw context
.getRuntime().newArgumentError(args
.length
, 3);
1063 if (args
.length
!= 2) throw context
.getRuntime().newArgumentError(args
.length
, 2);
1068 case 'A': // ?A | Time | Last access time for file1
1069 return context
.getRuntime().newFileStat(args
[1].convertToString().toString(), false).atime();
1070 case 'b': // ?b | boolean | True if file1 is a block device
1071 return RubyFileTest
.blockdev_p(recv
, args
[1]);
1072 case 'c': // ?c | boolean | True if file1 is a character device
1073 return RubyFileTest
.chardev_p(recv
, args
[1]);
1074 case 'C': // ?C | Time | Last change time for file1
1075 return context
.getRuntime().newFileStat(args
[1].convertToString().toString(), false).ctime();
1076 case 'd': // ?d | boolean | True if file1 exists and is a directory
1077 return RubyFileTest
.directory_p(recv
, args
[1]);
1078 case 'e': // ?e | boolean | True if file1 exists
1079 return RubyFileTest
.exist_p(recv
, args
[1]);
1080 case 'f': // ?f | boolean | True if file1 exists and is a regular file
1081 return RubyFileTest
.file_p(recv
, args
[1]);
1082 case 'g': // ?g | boolean | True if file1 has the \CF{setgid} bit
1083 return RubyFileTest
.setgid_p(recv
, args
[1]);
1084 case 'G': // ?G | boolean | True if file1 exists and has a group ownership equal to the caller's group
1085 return RubyFileTest
.grpowned_p(recv
, args
[1]);
1086 case 'k': // ?k | boolean | True if file1 exists and has the sticky bit set
1087 return RubyFileTest
.sticky_p(recv
, args
[1]);
1088 case 'M': // ?M | Time | Last modification time for file1
1089 return context
.getRuntime().newFileStat(args
[1].convertToString().toString(), false).mtime();
1090 case 'l': // ?l | boolean | True if file1 exists and is a symbolic link
1091 return RubyFileTest
.symlink_p(recv
, args
[1]);
1092 case 'o': // ?o | boolean | True if file1 exists and is owned by the caller's effective uid
1093 return RubyFileTest
.owned_p(recv
, args
[1]);
1094 case 'O': // ?O | boolean | True if file1 exists and is owned by the caller's real uid
1095 return RubyFileTest
.rowned_p(recv
, args
[1]);
1096 case 'p': // ?p | boolean | True if file1 exists and is a fifo
1097 return RubyFileTest
.pipe_p(recv
, args
[1]);
1098 case 'r': // ?r | boolean | True if file1 is readable by the effective uid/gid of the caller
1099 return RubyFileTest
.readable_p(recv
, args
[1]);
1100 case 'R': // ?R | boolean | True if file is readable by the real uid/gid of the caller
1101 // FIXME: Need to implement an readable_real_p in FileTest
1102 return RubyFileTest
.readable_p(recv
, args
[1]);
1103 case 's': // ?s | int/nil | If file1 has nonzero size, return the size, otherwise nil
1104 return RubyFileTest
.size_p(recv
, args
[1]);
1105 case 'S': // ?S | boolean | True if file1 exists and is a socket
1106 return RubyFileTest
.socket_p(recv
, args
[1]);
1107 case 'u': // ?u | boolean | True if file1 has the setuid bit set
1108 return RubyFileTest
.setuid_p(recv
, args
[1]);
1109 case 'w': // ?w | boolean | True if file1 exists and is writable by effective uid/gid
1110 return RubyFileTest
.writable_p(recv
, args
[1]);
1111 case 'W': // ?W | boolean | True if file1 exists and is writable by the real uid/gid
1112 // FIXME: Need to implement an writable_real_p in FileTest
1113 return RubyFileTest
.writable_p(recv
, args
[1]);
1114 case 'x': // ?x | boolean | True if file1 exists and is executable by the effective uid/gid
1115 return RubyFileTest
.executable_p(recv
, args
[1]);
1116 case 'X': // ?X | boolean | True if file1 exists and is executable by the real uid/gid
1117 return RubyFileTest
.executable_real_p(recv
, args
[1]);
1118 case 'z': // ?z | boolean | True if file1 exists and has a zero length
1119 return RubyFileTest
.zero_p(recv
, args
[1]);
1120 case '=': // ?= | boolean | True if the modification times of file1 and file2 are equal
1121 return context
.getRuntime().newFileStat(args
[1].convertToString().toString(), false).mtimeEquals(args
[2]);
1122 case '<': // ?< | boolean | True if the modification time of file1 is prior to that of file2
1123 return context
.getRuntime().newFileStat(args
[1].convertToString().toString(), false).mtimeLessThan(args
[2]);
1124 case '>': // ?> | boolean | True if the modification time of file1 is after that of file2
1125 return context
.getRuntime().newFileStat(args
[1].convertToString().toString(), false).mtimeGreaterThan(args
[2]);
1126 case '-': // ?- | boolean | True if file1 and file2 are identical
1127 return RubyFileTest
.identical_p(recv
, args
[1], args
[2]);
1129 throw new InternalError("unreachable code reached!");
1133 @JRubyMethod(name
= "`", required
= 1, module
= true, visibility
= PRIVATE
)
1134 public static IRubyObject
backquote(ThreadContext context
, IRubyObject recv
, IRubyObject aString
) {
1135 Ruby runtime
= context
.getRuntime();
1136 ByteArrayOutputStream output
= new ByteArrayOutputStream();
1138 RubyString string
= aString
.convertToString();
1139 int resultCode
= ShellLauncher
.runAndWait(runtime
, new IRubyObject
[] {string
}, output
);
1141 runtime
.getGlobalVariables().set("$?", RubyProcess
.RubyStatus
.newProcessStatus(runtime
, resultCode
));
1143 return RubyString
.newString(runtime
, output
.toByteArray());
1146 @JRubyMethod(name
= "srand", optional
= 1, module
= true, visibility
= PRIVATE
)
1147 public static RubyInteger
srand(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
1148 Ruby runtime
= context
.getRuntime();
1149 long oldRandomSeed
= runtime
.getRandomSeed();
1151 if (args
.length
> 0) {
1152 RubyInteger integerSeed
= args
[0].convertToInteger(MethodIndex
.TO_INT
, "to_int");
1153 runtime
.setRandomSeed(integerSeed
.getLongValue());
1155 // Not sure how well this works, but it works much better than
1156 // just currentTimeMillis by itself.
1157 runtime
.setRandomSeed(System
.currentTimeMillis() ^
1158 recv
.hashCode() ^ runtime
.incrementRandomSeedSequence() ^
1159 runtime
.getRandom().nextInt(Math
.max(1, Math
.abs((int)runtime
.getRandomSeed()))));
1161 runtime
.getRandom().setSeed(runtime
.getRandomSeed());
1162 return runtime
.newFixnum(oldRandomSeed
);
1165 @JRubyMethod(name
= "rand", optional
= 1, module
= true, visibility
= PRIVATE
)
1166 public static RubyNumeric
rand(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
1167 Ruby runtime
= context
.getRuntime();
1169 if (args
.length
== 0) {
1171 } else if (args
.length
== 1) {
1172 if (args
[0] instanceof RubyBignum
) {
1173 byte[] bigCeilBytes
= ((RubyBignum
) args
[0]).getValue().toByteArray();
1174 BigInteger bigCeil
= new BigInteger(bigCeilBytes
).abs();
1176 byte[] randBytes
= new byte[bigCeilBytes
.length
];
1177 runtime
.getRandom().nextBytes(randBytes
);
1179 BigInteger result
= new BigInteger(randBytes
).abs().mod(bigCeil
);
1181 return new RubyBignum(runtime
, result
);
1184 RubyInteger integerCeil
= (RubyInteger
)RubyKernel
.new_integer(context
, recv
, args
[0]);
1185 ceil
= Math
.abs(integerCeil
.getLongValue());
1187 throw runtime
.newArgumentError("wrong # of arguments(" + args
.length
+ " for 1)");
1191 return RubyFloat
.newFloat(runtime
, runtime
.getRandom().nextDouble());
1193 if (ceil
> Integer
.MAX_VALUE
) {
1194 return runtime
.newFixnum(Math
.abs(runtime
.getRandom().nextLong()) % ceil
);
1197 return runtime
.newFixnum(runtime
.getRandom().nextInt((int) ceil
));
1200 @JRubyMethod(name
= "syscall", required
= 1, optional
= 9, module
= true, visibility
= PRIVATE
)
1201 public static IRubyObject
syscall(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
1202 throw context
.getRuntime().newNotImplementedError("Kernel#syscall is not implemented in JRuby");
1205 @JRubyMethod(name
= {"system"}, required
= 1, rest
= true, module
= true, visibility
= PRIVATE
)
1206 public static RubyBoolean
system(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
1207 Ruby runtime
= context
.getRuntime();
1210 resultCode
= ShellLauncher
.runAndWait(runtime
, args
);
1211 } catch (Exception e
) {
1214 runtime
.getGlobalVariables().set("$?", RubyProcess
.RubyStatus
.newProcessStatus(runtime
, resultCode
));
1215 return runtime
.newBoolean(resultCode
== 0);
1218 @JRubyMethod(name
= {"exec"}, required
= 1, rest
= true, module
= true, visibility
= PRIVATE
)
1219 public static IRubyObject
exec(ThreadContext context
, IRubyObject recv
, IRubyObject
[] args
) {
1220 Ruby runtime
= context
.getRuntime();
1223 // TODO: exec should replace the current process.
1224 // This could be possible with JNA.
1225 resultCode
= ShellLauncher
.execAndWait(runtime
, args
);
1226 } catch (Exception e
) {
1227 throw runtime
.newErrnoENOENTError("cannot execute");
1230 return exit(recv
, new IRubyObject
[] {runtime
.newFixnum(resultCode
)});
1233 @JRubyMethod(name
= "fork", module
= true, visibility
= PRIVATE
)
1234 public static IRubyObject
fork(ThreadContext context
, IRubyObject recv
, Block block
) {
1235 Ruby runtime
= context
.getRuntime();
1237 if (!RubyInstanceConfig
.FORK_ENABLED
) {
1238 throw runtime
.newNotImplementedError("fork is unsafe and disabled by default on JRuby");
1241 if (block
.isGiven()) {
1242 int pid
= runtime
.getPosix().fork();
1246 block
.yield(context
, runtime
.getNil());
1247 } catch (RaiseException re
) {
1248 if (re
.getException() instanceof RubySystemExit
) {
1251 return exit_bang(recv
, new IRubyObject
[] {RubyFixnum
.minus_one(runtime
)});
1252 } catch (Throwable t
) {
1253 return exit_bang(recv
, new IRubyObject
[] {RubyFixnum
.minus_one(runtime
)});
1255 return exit_bang(recv
, new IRubyObject
[] {RubyFixnum
.zero(runtime
)});
1257 return runtime
.newFixnum(pid
);
1260 int result
= runtime
.getPosix().fork();
1263 return runtime
.getNil();
1266 return runtime
.newFixnum(result
);
1270 @JRubyMethod(frame
= true, module
= true)
1271 public static IRubyObject
tap(ThreadContext context
, IRubyObject recv
, Block block
) {
1272 block
.yield(context
, recv
);