Kernel
RubyGems 添加了 gem 方法以允许激活特定的 gem 版本,并覆盖了 Kernel 上的 require 方法,使 gem 看起来就好像它们存在于$LOAD_PATH
。有关更多详细信息,请参阅这些方法的文档。
内核模块包含在 Object 类中,所以它的方法在每个 Ruby 对象中都可用。
内核实例方法记录在类 Object 中,而模块方法记录在此处。这些方法在没有接收器的情况下被调用,因此可以用函数形式调用:
sprintf "%.1f", 1.234 #=> "1.2"
公共类方法
URI(s)显示源
返回uri
转换为 URI 对象。
# File lib/uri/common.rb, line 732
def URI(uri)
if uri.is_a?(URI::Generic)
uri
elsif uri = String.try_convert(uri)
URI.parse(uri)
else
raise ArgumentError,
"bad argument (expected URI object or URI string)"
end
end
open(path , mode [, perm]) →io 或零显示源
open(path , mode [, perm]) {|io| block } → obj
创建连接到给定流,文件或子流程的 IO 对象。
如果path
不以管道字符(|
)开头,则将其视为要使用指定模式打开的文件的名称(默认为“r”)。
mode
字符串可以是字符串,也可以是整数。如果它是一个整数,它必须是按位或开放(2)标志,例如 File :: RDWR 或 File :: EXCL。如果是字符串,则为“fmode”,“fmode:ext_enc”或“fmode:ext_enc:int_enc”。
有关mode
字符串指令的完整文档,请参阅 IO.new 的文档。
如果正在创建文件,则可以使用该perm
参数设置其初始权限。有关权限的描述,请参见 File.new和open(2)和 chmod(2)手册页。
如果指定了一个块,它将以 IO 对象作为参数进行调用,并且当块终止时 IO 将自动关闭。该调用返回该块的值。
如果path
以管道字符("|"
)开头,则会创建一个子进程,并通过一对管道连接到调用者。返回的 IO 对象可用于写入标准输入并从此子流程的标准输出中读取。
如果管道后面的命令是单个减号("|-"
),则 Ruby 分支,并且此子进程连接到父级。如果该命令不是"-"
,则该子进程运行该命令。
当子进程是 ruby(通过打开"|-"
)时,open
调用返回nil
。如果某个块与公开呼叫相关联,则该块将运行两次 - 一次在父级,一次在子级。
block 参数将是父级和nil
子级中的 IO 对象。父IO
对象将连接到孩子的$ stdin和$ stdout。子程序将在程序段结尾处终止。
示例
从“testfile”中读取:
open("testfile") do |f|
print f.gets
end
生产:
This is line one
打开一个子进程并读取其输出:
cmd = open("|date")
print cmd.gets
cmd.close
生产:
Wed Apr 9 08:56:31 CDT 2003
打开运行相同 Ruby 程序的子进程:
f = open("|-", "w+")
if f == nil
puts "in Child"
exit
else
puts "Got: #{f.gets}"
end
生产:
Got: in Child
使用块打开子进程以接收 IO 对象:
open "|-" do |f|
if f then
# parent process
puts "Got: #{f.gets}"
else
# child process
puts "in Child"
end
end
生产:
Got: in Child
static VALUE
rb_f_open(int argc, VALUE *argv)
{
ID to_open = 0;
int redirect = FALSE;
if (argc >= 1) {
CONST_ID(to_open, "to_open");
if (rb_respond_to(argv[0], to_open)) {
redirect = TRUE;
}
else {
VALUE tmp = argv[0];
FilePathValue(tmp);
if (NIL_P(tmp)) {
redirect = TRUE;
}
else {
VALUE cmd = check_pipe_command(tmp);
if (!NIL_P(cmd)) {
argv[0] = cmd;
return rb_io_s_popen(argc, argv, rb_cIO);
}
}
}
}
if (redirect) {
VALUE io = rb_funcallv(argv[0], to_open, argc-1, argv+1);
if (rb_block_given_p()) {
return rb_ensure(rb_yield, io, io_close, io);
}
return io;
}
return rb_io_s_open(argc, argv, rb_cFile);
}
另外别名为:open_uri_original_open,open_uri_original_open
pp(* objs)显示源文件
以漂亮的形式打印参数。
pp 返回参数(s)。
# File lib/pp.rb, line 19
def pp(*objs)
objs.each {|obj|
PP.pp(obj)
}
objs.size <= 1 ? objs.first : objs
end
私有类方法
open_uri_original_open(*args)
别名为:open
公共实例方法
Array(arg) →数组显示源
作为数组返回arg
。
首先在arg
上尝试调用to_ary
,然后to_a
。
Array(1..5) #=> [1, 2, 3, 4, 5]
static VALUE
rb_f_array(VALUE obj, VALUE arg)
{
return rb_Array(arg);
}
BigDecimal(* args)显示源文件
另请参阅 BigDecimal.new
static VALUE
BigDecimal_global_new(int argc, VALUE *argv, VALUE self)
{
ENTER(1);
Real *pv;
VALUE obj;
obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, 0);
GUARD_OBJ(pv, BigDecimal_new(argc, argv));
if (ToValue(pv)) pv = VpCopy(NULL, pv);
RTYPEDDATA_DATA(obj) = pv;
return pv->obj = obj;
}
Complex(x,y)→数字显示源
返回 x + i * y;
Complex(1, 2) #=> (1+2i)
Complex('1+2i') #=> (1+2i)
Complex(nil) #=> TypeError
Complex(1, nil) #=> TypeError
字符串形式的语法:
string form = extra spaces , complex , extra spaces ;
complex = real part | [ sign ] , imaginary part
| real part , sign , imaginary part
| rational , "@" , rational ;
real part = rational ;
imaginary part = imaginary unit | unsigned rational , imaginary unit ;
rational = [ sign ] , unsigned rational ;
unsigned rational = numerator | numerator , "/" , denominator ;
numerator = integer part | fractional part | integer part , fractional part ;
denominator = digits ;
integer part = digits ;
fractional part = "." , digits , [ ( "e" | "E" ) , [ sign ] , digits ] ;
imaginary unit = "i" | "I" | "j" | "J" ;
sign = "-" | "+" ;
digits = digit , { digit | "_" , digit };
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
extra spaces = ? \s* ? ;
请参阅 String#to_c。
static VALUE
nucomp_f_complex(int argc, VALUE *argv, VALUE klass)
{
return nucomp_s_convert(argc, argv, rb_cComplex);
}
Float(p1) 显示源
static VALUE rb_f_float(VALUE obj, VALUE arg))
Hash(arg) →哈希显示源文件
通过调用 arg .to_hash
将 arg 转换为一个Hash
。当arg是nil
或[]
时,返回空Hash
。
Hash([]) #=> {}
Hash(nil) #=> {}
Hash(key: :value) #=> {:key => :value}
Hash([1, 2, 3]) #=> TypeError
static VALUE
rb_f_hash(VALUE obj, VALUE arg)
{
return rb_Hash(arg);
}
Integer(arg, base=0)→整数显示源文件
将 arg 转换为Integer
。数字类型直接转换(浮点数被截断)。基数(0或2和36之间)是整数字符串表示的基数。如果 ARG 是String
,当基极被省略或等于零,基数指示符(0
,0b
,和0x
)被兑现。无论如何,字符串应严格符合数字表示。这种行为不同于String#to_i
。to_int
然后,首先尝试转换非字符串值to_i
。传递nil
引发 TypeError。
Integer(123.999) #=> 123
Integer("0x1a") #=> 26
Integer(Time.new) #=> 1204973019
Integer("0930", 10) #=> 930
Integer("111", 2) #=> 7
Integer(nil) #=> TypeError
static VALUE
rb_f_integer(int argc, VALUE *argv, VALUE obj)
{
VALUE arg = Qnil;
int base = 0;
switch (argc) {
case 2:
base = NUM2INT(argv[1]);
case 1:
arg = argv[0];
break;
default:
/* should cause ArgumentError */
rb_scan_args(argc, argv, "11", NULL, NULL);
}
return rb_convert_to_integer(arg, base);
}
Pathname(path) →路径名显示源
从给定字符串创建一个新的路径名对象path
,并返回路径名对象。
为了使用这个构造函数,你必须首先需要 Pathname 标准库扩展。
require 'pathname'
Pathname("/home/zzak")
#=> #<Pathname:/home/zzak>
有关更多信息,另请参阅 Pathname.new。
static VALUE
path_f_pathname(VALUE self, VALUE str)
{
return rb_class_new_instance(1, &str, rb_cPathname);
}
Rational(x,y)→数字显示源
返回 x / y;
Rational(1, 2) #=> (1/2)
Rational('1/2') #=> (1/2)
Rational(nil) #=> TypeError
Rational(1, nil) #=> TypeError
字符串形式的语法:
string form = extra spaces , rational , extra spaces ;
rational = [ sign ] , unsigned rational ;
unsigned rational = numerator | numerator , "/" , denominator ;
numerator = integer part | fractional part | integer part , fractional part ;
denominator = digits ;
integer part = digits ;
fractional part = "." , digits , [ ( "e" | "E" ) , [ sign ] , digits ] ;
sign = "-" | "+" ;
digits = digit , { digit | "_" , digit } ;
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
extra spaces = ? \s* ? ;
请参阅 String#to_r。
static VALUE
nurat_f_rational(int argc, VALUE *argv, VALUE klass)
{
return nurat_s_convert(argc, argv, rb_cRational);
}
String(arg) →字符串显示源文件
将arg返回为一个 String
。
首先尝试调用它的to_str
方法,然后调用它的to_s
方法。
String(self) #=> "main"
String(self.class) #=> "Object"
String(123456) #=> "123456"
static VALUE
rb_f_string(VALUE obj, VALUE arg)
{
return rb_String(arg);
}
__callee__→符号显示源
以符号形式返回当前方法的被调用名称。如果在方法之外调用,则返回nil
。
static VALUE
rb_f_callee_name(void)
{
ID fname = prev_frame_callee(); /* need *callee* ID */
if (fname) {
return ID2SYM(fname);
}
else {
return Qnil;
}
}
__dir__→字符串显示源文件
返回调用此方法的文件的目录的规范化绝对路径。这意味着路径中的符号链接已解决。如果__FILE__
是nil
,它会返回nil
。返回值等于File.dirname(File.realpath(__FILE__))
。
static VALUE
f_current_dirname(void)
{
VALUE base = rb_current_realfilepath();
if (NIL_P(base)) {
return Qnil;
}
base = rb_file_dirname(base);
return base;
}
__method__→符号显示源代码
以符号的形式返回当前方法定义的名称。如果在方法之外调用,则返回nil
。
static VALUE
rb_f_method_name(void)
{
ID fname = prev_frame_func(); /* need *method* ID */
if (fname) {
return ID2SYM(fname);
}
else {
return Qnil;
}
}
cmd
→字符串显示源
返回子 shell 中运行 cmd 的标准输出。内置的语法%x{...}
使用这种方法。设置$?
为进程状态。
%x`date` #=> "Wed Apr 9 08:56:30 CDT 2003\n"
%x`ls testdir`.split[1] #=> "main.rb"
%x`echo oops && exit 99` #=> "oops\n"
$?.exitstatus #=> 99
static VALUE
rb_f_backquote(VALUE obj, VALUE str)
{
VALUE port;
VALUE result;
rb_io_t *fptr;
SafeStringValue(str);
rb_last_status_clear();
port = pipe_open_s(str, "r", FMODE_READABLE|DEFAULT_TEXTMODE, NULL);
if (NIL_P(port)) return rb_str_new(0,0);
GetOpenFile(port, fptr);
result = read_all(fptr, remain_size(fptr), Qnil);
rb_io_close(port);
rb_io_fptr_finalize(fptr);
rb_gc_force_recycle(port); /* also guards from premature GC */
return result;
}
中止显示源
Kernel::abort(msg)
abort(msg)
通过调用立即终止执行Kernel.exit(false)
。如果给出 msg,则在终止之前将其写入 STDERR。
VALUE
rb_f_abort(int argc, const VALUE *argv)
{
rb_check_arity(argc, 0, 1);
if (argc == 0) {
if (!NIL_P(GET_THREAD()->errinfo)) {
ruby_error_print();
}
rb_exit(EXIT_FAILURE);
}
else {
VALUE args[2];
args[1] = args[0] = argv[0];
StringValue(args[0]);
rb_io_puts(1, args, rb_stderr);
args[0] = INT2NUM(EXIT_FAILURE);
rb_exc_raise(rb_class_new_instance(2, args, rb_eSystemExit));
}
UNREACHABLE;
}
at_exit {block}→proc显示源文件
将块转换为Proc
对象(因此将其绑定到调用点)并在程序退出时将其注册为执行。如果注册了多个处理程序,则它们将以与注册相反的顺序执行。
def do_at_exit(str1)
at_exit { print str1 }
end
at_exit { puts "cruel world" }
do_at_exit("goodbye ")
exit
produces:
goodbye cruel world
static VALUE
rb_f_at_exit(void)
{
VALUE proc;
if (!rb_block_given_p()) {
rb_raise(rb_eArgError, "called without a block");
}
proc = rb_block_proc();
rb_set_end_proc(rb_call_end_proc, proc);
return proc;
}
autoload(module, filename) →无显示源
注册第一次访问该模块(可能是一个String
或符号)时要加载(使用Kernel::require
)的文件名。
autoload(:MyModule, "/usr/local/lib/modules/my_module.rb")
static VALUE
rb_f_autoload(VALUE obj, VALUE sym, VALUE file)
{
VALUE klass = rb_class_real(rb_vm_cbase());
if (NIL_P(klass)) {
rb_raise(rb_eTypeError, "Can not set autoload on singleton class");
}
return rb_mod_autoload(klass, sym, file);
}
autoload?(name) →字符串或零显示源
如果名称被注册为,则返回要加载autoload
的文件名。
autoload(:B, "b")
autoload?(:B) #=> "b"
static VALUE
rb_f_autoload_p(VALUE obj, VALUE sym)
{
/* use rb_vm_cbase() as same as rb_f_autoload. */
VALUE klass = rb_vm_cbase();
if (NIL_P(klass)) {
return Qnil;
}
return rb_mod_autoload_p(klass, sym);
}
binding →a_binding显示源
返回一个Binding
对象,描述调用时的变量和方法绑定。调用eval
此环境中执行评估命令时可以使用此对象。另请参阅类Binding
的描述。
def get_binding(param)
binding
end
b = get_binding("hello")
eval("param", b) #=> "hello"
static VALUE
rb_f_binding(VALUE self)
{
return rb_binding_new();
}
block_given?→true 或 false 显示来源
如果yield
会在当前上下文中执行块返回true
。iterator?
表格被轻度弃用。
def try
if block_given?
yield
else
"no block"
end
end
try #=> "no block"
try { "hello" } #=> "hello"
try do "hello" end #=> "hello"
VALUE
rb_f_block_given_p(void)
{
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = th->cfp;
cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
if (cfp != NULL && VM_CF_BLOCK_HANDLER(cfp) != VM_BLOCK_HANDLER_NONE) {
return Qtrue;
}
else {
return Qfalse;
}
}
callcc {|cont| block } →obj 显示源
生成一个 Continuation 对象,并将其传递给关联的块。您需要require 'continuation'
在使用此方法之前。执行一个cont.call
将导致 callcc 返回(如同在块的结尾处)。callcc 返回的值是该块的值或传递给 cont 的值.call
。有关更多详细信息,请参见延续课程 另请参阅 #throw,了解用于展开调用堆栈的其他机制。
static VALUE
rb_callcc(VALUE self)
{
volatile int called;
volatile VALUE val = cont_capture(&called);
if (called) {
return val;
}
else {
return rb_yield(val);
}
}
caller(start=1, length=nil) →数组或无显示源
caller(range) → 数组或无
返回当前执行堆栈 - 包含表单file:line
或者file:line: in `method'
中的字符串的数组。
可选的开始参数确定堆栈顶部要忽略的初始堆栈条目的数量。
第二个可选length
参数可用于限制从堆栈返回多少条目。
如果 start 大于当前执行堆栈的大小,则返回nil
。
或者,您可以传递一个范围,它将返回一个包含指定范围内条目的数组。
def a(skip)
caller(skip)
end
def b(skip)
a(skip)
end
def c(skip)
b(skip)
end
c(0) #=> ["prog:2:in `a'", "prog:5:in `b'", "prog:8:in `c'", "prog:10:in `<main>'"]
c(1) #=> ["prog:5:in `b'", "prog:8:in `c'", "prog:11:in `<main>'"]
c(2) #=> ["prog:8:in `c'", "prog:12:in `<main>'"]
c(3) #=> ["prog:13:in `<main>'"]
c(4) #=> []
c(5) #=> nil
static VALUE
rb_f_caller(int argc, VALUE *argv)
{
return vm_backtrace_to_ary(GET_THREAD(), argc, argv, 1, 1, 1);
}
caller_locations(start = 1,length = nil)→array 或 nil 显示源文件
caller_locations(range)→array 或 nil
返回当前的执行堆栈 - 一个包含回溯位置对象的数组。
有关更多信息,请参阅 Thread :: Backtrace :: Location。
可选的开始参数确定堆栈顶部要忽略的初始堆栈条目的数量。
第二个可选length
参数可用于限制从堆栈返回多少条目。
如果 start 大于当前执行堆栈的大小,则返回nil
。
或者,您可以传递一个范围,它将返回一个包含指定范围内条目的数组。
static VALUE
rb_f_caller_locations(int argc, VALUE *argv)
{
return vm_backtrace_to_ary(GET_THREAD(), argc, argv, 1, 1, 0);
}
catch(tag){| tag | 块}→ obj 显示源
catch
执行其块。如果throw
未被调用,则该块正常执行,并catch
返回最后一个表达式的值。
catch(1) { 123 } # => 123
如果throw(tag2, val)
被调用,Ruby 搜索了它的堆栈一个catch
块,其tag
具有相同object_id
的 TAG2。找到时,块停止执行并返回 val(或者,nil
如果没有给出第二个参数throw
)。
catch(1) { throw(1, 456) } # => 456
catch(1) { throw(1) } # => nil
当tag
作为第一个参数传递时,将catch
其作为该块的参数。
catch(1) {|x| x + 2 } # => 3
如果tag
未指定,则catch
产生一个新的唯一对象(从Object.new
)作为块参数。这个对象可以被用作参数throw
,并且会匹配正确的catch
块。
catch do |obj_A|
catch do |obj_B|
throw(obj_B, 123)
puts "This puts is not reached"
end
puts "This puts is displayed"
456
end
# => 456
catch do |obj_A|
catch do |obj_B|
throw(obj_A, 123)
puts "This puts is still not reached"
end
puts "Now this puts is also not reached"
456
end
# => 123
static VALUE
rb_f_catch(int argc, VALUE *argv)
{
VALUE tag;
if (argc == 0) {
tag = rb_obj_alloc(rb_cObject);
}
else {
rb_scan_args(argc, argv, "01", &tag);
}
return rb_catch_obj(tag, catch_i, 0);
}
chomp→$ _显示源
chomp(string) → $_
相当于$_ = $_.chomp(string)
。看String#chomp
。仅在指定-p / -n命令行选项时可用。
static VALUE
rb_f_chomp(int argc, VALUE *argv)
{
VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("chomp"), argc, argv);
rb_lastline_set(str);
return str;
}
chop→$ _显示源
相当于($_.dup).chop!
,除了nil
永远不会返回。看String#chop!
。仅在指定-p / -n命令行选项时可用。
static VALUE
rb_f_chop(void)
{
VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("chop"), 0, 0);
rb_lastline_set(str);
return str;
}
eval(string [,binding [,filename,lineno]])→obj 显示源文件
在字符串中计算 Ruby 表达式。如果给定了绑定,那必须是一个Binding
对象,评估是在其上下文中执行的。如果存在可选的文件名和 lineno 参数,则会在报告语法错误时使用它们。
def get_binding(str)
return binding
end
str = "hello"
eval "str + ' Fred'" #=> "hello Fred"
eval "str + ' Fred'", get_binding("bye") #=> "bye Fred"
VALUE
rb_f_eval(int argc, const VALUE *argv, VALUE self)
{
VALUE src, scope, vfile, vline;
VALUE file = Qundef;
int line = 1;
rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
SafeStringValue(src);
if (argc >= 3) {
StringValue(vfile);
}
if (argc >= 4) {
line = NUM2INT(vline);
}
if (!NIL_P(vfile))
file = vfile;
return eval_string(self, src, scope, file, line);
}
exec(env,command ...,options)显示源文件
通过运行给定的外部命令来替换当前进程,该命令可以采用以下形式之一:
exec(commandline)
传递给标准 shell 的命令行字符串
exec(cmdname, arg1, ...)
命令名称和一个或多个参数(无shell)
exec([cmdname, argv0], arg1, ...)
命令名,argv 和零个或多个参数(无 shell)
在第一种形式中,字符串被视为一个命令行,在执行之前需要进行shell扩展。
标准外壳总是意味着"/bin/sh"
在类 Unix 系统上,与 Windows NT 系列相同,ENV["RUBYSHELL"]
或ENV["COMSPEC"]
类似。
如果来自第一个 form(exec("command")
)的字符串遵循以下简单规则:
- 没有元字符
- 没有外壳保留字,也没有特殊的内置
- Ruby不使用shell就直接调用该命令
您可以通过向字符串添加“;”来强制执行shell调用(因为“;”是元字符)。
请注意,此行为是PID得到(spawn()和返回值可观察到的IO#PID为IO.popen)是调用命令的PID,而不是外壳。
在第二个窗体(exec("command1", "arg1", ...)
)中,第一个被作为命令名,其余的被作为参数传递给没有shell扩展的命令。
在第三种形式(exec(["command", "argv0"], "arg1", ...)
)中,在命令开始处启动一个双元素数组,第一个元素是要执行的命令,第二个参数用作argv[0]
值,可能会在进程列表中显示。
为了执行该命令,使用了一个exec(2)
系统调用,所以运行命令可以继承原始程序的某些环境(包括打开的文件描述符)。
此行为是由给定的修改env
和 options
参数。有关详细信息,请参阅:: spawn。
如果该命令执行失败(通常Errno::ENOENT
是未找到该命令), 则会引发SystemCallError异常。
此方法根据系统调用options
之前的给定值修改进程属性 exec(2)
。有关给定的更多细节,请参阅:: spawn options
。
当exec(2)
系统调用失败时,修改后的属性可能会保留。
例如,硬资源限制不可恢复。
考虑使用:: spawn或#system创建一个子进程,如果这是不可接受的。
exec "echo *" # echoes list of files in current directory
# never get here
exec "echo", "*" # echoes an asterisk
# never get here
exit(status=true)
Kernel::exit(status=true)
Process::exit(status=true)
通过引发SystemExit
异常来启动Ruby脚本的终止。这个例外可能被捕获。可选参数用于将状态码返回到调用环境。true
和FALSE
的状态分别意味着成功和失败。其他整数值的解释是依赖于系统的。
begin
exit
puts "never get here"
rescue SystemExit
puts "rescued a SystemExit exception"
end
puts "after begin block"
生成:
rescued a SystemExit exception
after begin block
在终止之前,Ruby执行任何at_exit
函数(请参阅Kernel :: at_exit)并运行任何对象终结器(请参阅ObjectSpace.define_finalizer)。
at_exit { puts "at_exit function" }
ObjectSpace.define_finalizer("string", proc { puts "in finalizer" })
exit
生成:
at_exit function
in finalizer
VALUE
rb_f_exit(int argc, const VALUE *argv)
{
int istatus;
if (rb_check_arity(argc, 0, 1) == 1) {
istatus = exit_status_code(argv[0]);
}
else {
istatus = EXIT_SUCCESS;
}
rb_exit(istatus);
UNREACHABLE;
}
exit!(status=false)
立即退出流程。没有退出处理程序运行。状态作为退出状态返回到底层系统。
Process.exit!(true)
static VALUE
rb_f_exit_bang(int argc, VALUE *argv, VALUE obj)
{
int istatus;
if (rb_check_arity(argc, 0, 1) == 1) {
istatus = exit_status_code(argv[0]);
}
else {
istatus = EXIT_FAILURE;
}
_exit(istatus);
UNREACHABLE;
}
fail
fail(string)
fail(exception [, string [, array]])
不带任何参数,引发异常的$!
或提出了RuntimeError
,如果$!
是nil
。用单个String
参数,将RuntimeError
字符串作为消息引发。否则,第一个参数应该是Exception
类的名称(或Exception
发送exception
消息时返回对象的对象)。可选的第二个参数设置与异常关联的消息,第三个参数是一个回调信息数组。例外被块的rescue
条款捕获begin...end
。
raise "Failed to create socket"
raise ArgumentError, "No parameters", caller
static VALUE
rb_f_raise(int argc, VALUE *argv)
{
VALUE err;
VALUE opts[raise_max_opt], *const cause = &opts[raise_opt_cause];
argc = extract_raise_opts(argc, argv, opts);
if (argc == 0) {
if (*cause != Qundef) {
rb_raise(rb_eArgError, "only cause is given with no arguments");
}
err = get_errinfo();
if (!NIL_P(err)) {
argc = 1;
argv = &err;
}
}
rb_raise_jump(rb_make_exception(argc, argv), *cause);
UNREACHABLE;
}
fork [{ block }] → integer or nil
fork [{ block }] → integer or nil
创建一个子流程。如果指定了一个块,则该块在子进程中运行,并且子进程终止,状态为零。否则,fork
调用返回两次,一次返回父进程,返回该进程的ID,一次进入子进程,返回nil。子进程可以退出使用,Kernel.exit!
以避免运行任何 at_exit
功能。父母程序应该Process.wait
用来收集其子女的终止状态或用于Process.detach
注册他们的状态不感兴趣; 否则,操作系统可能会累积僵尸进程。
线程调用fork是创建的子进程中唯一的线程。fork不会复制其他线程。
如果fork不可用,则Process.respond_to?(:fork)返回false。
请注意,fork(2)在Windows和NetBSD 4等平台上不可用。因此,您应该使用spawn()而不是fork()。
static VALUE
rb_f_fork(VALUE obj)
{
rb_pid_t pid;
switch (pid = rb_fork_ruby(NULL)) {
case 0:
rb_thread_atfork();
if (rb_block_given_p()) {
int status;
rb_protect(rb_yield, Qundef, &status);
ruby_stop(status);
}
return Qnil;
case -1:
rb_sys_fail("fork(2)");
return Qnil;
default:
return PIDT2NUM(pid);
}
}
format(format_string [, arguments...] ) → stringclick to toggle source
返回将format_string应用于任何其他参数所产生的字符串。在格式字符串中,格式序列以外的任何字符都将被复制到结果中。
格式序列的语法如下。
%[flags][width][.precision]type
一个格式序列由一个百分号组成,后跟可选的标志,宽度和精度指示符,然后以字段类型字符结尾。字段类型控制相应sprintf
参数如何 解释,而标志修改解释。
字段类型字符是:
Field | Integer Format
------+--------------------------------------------------------------
b | Convert argument as a binary number.
| Negative numbers will be displayed as a two's complement
| prefixed with `..1'.
B | Equivalent to `b', but uses an uppercase 0B for prefix
| in the alternative format by #.
d | Convert argument as a decimal number.
i | Identical to `d'.
o | Convert argument as an octal number.
| Negative numbers will be displayed as a two's complement
| prefixed with `..7'.
u | Identical to `d'.
x | Convert argument as a hexadecimal number.
| Negative numbers will be displayed as a two's complement
| prefixed with `..f' (representing an infinite string of
| leading 'ff's).
X | Equivalent to `x', but uses uppercase letters.
Field | Float Format
------+--------------------------------------------------------------
e | Convert floating point argument into exponential notation
| with one digit before the decimal point as [-]d.dddddde[+-]dd.
| The precision specifies the number of digits after the decimal
| point (defaulting to six).
E | Equivalent to `e', but uses an uppercase E to indicate
| the exponent.
f | Convert floating point argument as [-]ddd.dddddd,
| where the precision specifies the number of digits after
| the decimal point.
g | Convert a floating point number using exponential form
| if the exponent is less than -4 or greater than or
| equal to the precision, or in dd.dddd form otherwise.
| The precision specifies the number of significant digits.
G | Equivalent to `g', but use an uppercase `E' in exponent form.
a | Convert floating point argument as [-]0xh.hhhhp[+-]dd,
| which is consisted from optional sign, "0x", fraction part
| as hexadecimal, "p", and exponential part as decimal.
A | Equivalent to `a', but use uppercase `X' and `P'.
Field | Other Format
------+--------------------------------------------------------------
c | Argument is the numeric code for a single character or
| a single character string itself.
p | The valuing of argument.inspect.
s | Argument is a string to be substituted. If the format
| sequence contains a precision, at most that many characters
| will be copied.
% | A percent sign itself will be displayed. No argument taken.
标志修改格式的行为。标志字符是:
Flag | Applies to | Meaning
---------+---------------+-----------------------------------------
space | bBdiouxX | Leave a space at the start of
| aAeEfgG | non-negative numbers.
| (numeric fmt) | For `o', `x', `X', `b' and `B', use
| | a minus sign with absolute value for
| | negative values.
---------+---------------+-----------------------------------------
(digit)$ | all | Specifies the absolute argument number
| | for this field. Absolute and relative
| | argument numbers cannot be mixed in a
| | sprintf string.
---------+---------------+-----------------------------------------
# | bBoxX | Use an alternative format.
| aAeEfgG | For the conversions `o', increase the precision
| | until the first digit will be `0' if
| | it is not formatted as complements.
| | For the conversions `x', `X', `b' and `B'
| | on non-zero, prefix the result with ``0x'',
| | ``0X'', ``0b'' and ``0B'', respectively.
| | For `a', `A', `e', `E', `f', `g', and 'G',
| | force a decimal point to be added,
| | even if no digits follow.
| | For `g' and 'G', do not remove trailing zeros.
---------+---------------+-----------------------------------------
+ | bBdiouxX | Add a leading plus sign to non-negative
| aAeEfgG | numbers.
| (numeric fmt) | For `o', `x', `X', `b' and `B', use
| | a minus sign with absolute value for
| | negative values.
---------+---------------+-----------------------------------------
- | all | Left-justify the result of this conversion.
---------+---------------+-----------------------------------------
0 (zero) | bBdiouxX | Pad with zeros, not spaces.
| aAeEfgG | For `o', `x', `X', `b' and `B', radix-1
| (numeric fmt) | is used for negative numbers formatted as
| | complements.
---------+---------------+-----------------------------------------
* | all | Use the next argument as the field width.
| | If negative, left-justify the result. If the
| | asterisk is followed by a number and a dollar
| | sign, use the indicated argument as the width.
flags的示例:
# `+' and space flag specifies the sign of non-negative numbers.
sprintf("%d", 123) #=> "123"
sprintf("%+d", 123) #=> "+123"
sprintf("% d", 123) #=> " 123"
# `#' flag for `o' increases number of digits to show `0'.
# `+' and space flag changes format of negative numbers.
sprintf("%o", 123) #=> "173"
sprintf("%#o", 123) #=> "0173"
sprintf("%+o", -123) #=> "-173"
sprintf("%o", -123) #=> "..7605"
sprintf("%#o", -123) #=> "..7605"
# `#' flag for `x' add a prefix `0x' for non-zero numbers.
# `+' and space flag disables complements for negative numbers.
sprintf("%x", 123) #=> "7b"
sprintf("%#x", 123) #=> "0x7b"
sprintf("%+x", -123) #=> "-7b"
sprintf("%x", -123) #=> "..f85"
sprintf("%#x", -123) #=> "0x..f85"
sprintf("%#x", 0) #=> "0"
# `#' for `X' uses the prefix `0X'.
sprintf("%X", 123) #=> "7B"
sprintf("%#X", 123) #=> "0X7B"
# `#' flag for `b' add a prefix `0b' for non-zero numbers.
# `+' and space flag disables complements for negative numbers.
sprintf("%b", 123) #=> "1111011"
sprintf("%#b", 123) #=> "0b1111011"
sprintf("%+b", -123) #=> "-1111011"
sprintf("%b", -123) #=> "..10000101"
sprintf("%#b", -123) #=> "0b..10000101"
sprintf("%#b", 0) #=> "0"
# `#' for `B' uses the prefix `0B'.
sprintf("%B", 123) #=> "1111011"
sprintf("%#B", 123) #=> "0B1111011"
# `#' for `e' forces to show the decimal point.
sprintf("%.0e", 1) #=> "1e+00"
sprintf("%#.0e", 1) #=> "1.e+00"
# `#' for `f' forces to show the decimal point.
sprintf("%.0f", 1234) #=> "1234"
sprintf("%#.0f", 1234) #=> "1234."
# `#' for `g' forces to show the decimal point.
# It also disables stripping lowest zeros.
sprintf("%g", 123.4) #=> "123.4"
sprintf("%#g", 123.4) #=> "123.400"
sprintf("%g", 123456) #=> "123456"
sprintf("%#g", 123456) #=> "123456."
字段宽度是一个可选的整数,随后可以选择一个句点和一个精度。宽度指定将写入该字段结果的最小字符数。
宽度示例:
# padding is done by spaces, width=20
# 0 or radix-1. <------------------>
sprintf("%20d", 123) #=> " 123"
sprintf("%+20d", 123) #=> " +123"
sprintf("%020d", 123) #=> "00000000000000000123"
sprintf("%+020d", 123) #=> "+0000000000000000123"
sprintf("% 020d", 123) #=> " 0000000000000000123"
sprintf("%-20d", 123) #=> "123 "
sprintf("%-+20d", 123) #=> "+123 "
sprintf("%- 20d", 123) #=> " 123 "
sprintf("%020x", -123) #=> "..ffffffffffffffff85"
对于数字字段,精度控制显示的小数位数。对于字符串字段,精度决定了要从字符串复制的最大字符数。(因此,格式序列 %10.10s
总是对结果贡献正好十个字符。)
精度示例:
# precision for `d', 'o', 'x' and 'b' is
# minimum number of digits <------>
sprintf("%20.8d", 123) #=> " 00000123"
sprintf("%20.8o", 123) #=> " 00000173"
sprintf("%20.8x", 123) #=> " 0000007b"
sprintf("%20.8b", 123) #=> " 01111011"
sprintf("%20.8d", -123) #=> " -00000123"
sprintf("%20.8o", -123) #=> " ..777605"
sprintf("%20.8x", -123) #=> " ..ffff85"
sprintf("%20.8b", -11) #=> " ..110101"
# "0x" and "0b" for `#x' and `#b' is not counted for
# precision but "0" for `#o' is counted. <------>
sprintf("%#20.8d", 123) #=> " 00000123"
sprintf("%#20.8o", 123) #=> " 00000173"
sprintf("%#20.8x", 123) #=> " 0x0000007b"
sprintf("%#20.8b", 123) #=> " 0b01111011"
sprintf("%#20.8d", -123) #=> " -00000123"
sprintf("%#20.8o", -123) #=> " ..777605"
sprintf("%#20.8x", -123) #=> " 0x..ffff85"
sprintf("%#20.8b", -11) #=> " 0b..110101"
# precision for `e' is number of
# digits after the decimal point <------>
sprintf("%20.8e", 1234.56789) #=> " 1.23456789e+03"
# precision for `f' is number of
# digits after the decimal point <------>
sprintf("%20.8f", 1234.56789) #=> " 1234.56789000"
# precision for `g' is number of
# significant digits <------->
sprintf("%20.8g", 1234.56789) #=> " 1234.5679"
# <------->
sprintf("%20.8g", 123456789) #=> " 1.2345679e+08"
# precision for `s' is
# maximum number of characters <------>
sprintf("%20.8s", "string test") #=> " string t"
示例:
sprintf("%d %04x", 123, 123) #=> "123 007b"
sprintf("%08b '%4s'", 123, 123) #=> "01111011 ' 123'"
sprintf("%1$*2$s %2$d %1$s", "hello", 8) #=> " hello 8 hello"
sprintf("%1$*2$s %2$d", "hello", -8) #=> "hello -8"
sprintf("%+g:% g:%-g", 1.23, 1.23, 1.23) #=> "+1.23: 1.23:1.23"
sprintf("%u", -123) #=> "-123"
对于更复杂的格式,Ruby支持按名称引用。%<name>的样式使用格式样式,但%{name}样式不会。
例子:
sprintf("%<foo>d : %<bar>f", { :foo => 1, :bar => 2 })
#=> 1 : 2.000000
sprintf("%{foo}f", { :foo => 1 })
# => "1f"
gets(sep=$/ [, getline_args]) → string or nil
gets(limit [, getline_args]) → string or nil
gets(sep, limit [, getline_args]) → string or nil
如果命令行中没有文件,则从(或)$_
中的文件列表中返回(并分配)下一行,或者从标准输入中返回下一行。在文件结尾处返回。可选参数指定记录分隔符。分隔符包含在每条记录的内容中。读取整个内容的分隔符和一个零长度分隔符一次读取输入的一个段落,其中段落被两个连续的换行符分隔。如果第一个参数是一个整数,或者给出了可选的第二个参数,则返回的字符串不会超过以字节为单位的给定值。如果存在多个文件名,将一次读取一个文件的内容。ARGV$*nilnilARGVgets(nil)
ARGV << "testfile"
print while gets
生成:
This is line one
This is line two
This is line three
And so on...
使用$_
隐式参数进行编程的风格在Ruby社区中逐渐失宠。
global_variables → array
返回全局变量名称的数组。
global_variables.grep /std/ #=> [:$stdin, :$stdout, :$stderr]
VALUE
rb_f_global_variables(void)
{
VALUE ary = rb_ary_new();
VALUE sym, backref = rb_backref_get();
rb_id_table_foreach(rb_global_tbl, gvar_i, (void *)ary);
if (!NIL_P(backref)) {
char buf[2];
int i, nmatch = rb_match_count(backref);
buf[0] = '$';
for (i = 1; i <= nmatch; ++i) {
if (!rb_match_nth_defined(i, backref)) continue;
if (i < 10) {
/* probably reused, make static ID */
buf[1] = (char)(i + '0');
sym = ID2SYM(rb_intern2(buf, 2));
}
else {
/* dynamic symbol */
sym = rb_str_intern(rb_sprintf("$%d", i));
}
rb_ary_push(ary, sym);
}
}
return ary;
}
gsub(pattern) {|...| block } → $_
等同于$_.gsub...
,除了$_
将在更换发生时更新。仅在指定-p / -n命令行选项时可用。
static VALUE
rb_f_gsub(int argc, VALUE *argv)
{
VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("gsub"), argc, argv);
rb_lastline_set(str);
return str;
}
iterator? → true or false
返回true
是否yield
会在当前上下文中执行块。该iterator?
表格被轻度弃用。
def try
if block_given?
yield
else
"no block"
end
end
try #=> "no block"
try { "hello" } #=> "hello"
try do "hello" end #=> "hello"
static VALUE
rb_f_block_given_p(void)
{
rb_execution_context_t *ec = GET_EC();
rb_control_frame_t *cfp = ec->cfp;
cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
if (cfp != NULL && VM_CF_BLOCK_HANDLER(cfp) != VM_BLOCK_HANDLER_NONE) {
return Qtrue;
}
else {
return Qfalse;
}
}
lambda { |...| block } → a_proc
相当于Proc.new
,除了生成的Proc对象检查调用时传递的参数的数量。
VALUE
rb_block_lambda(void)
{
return proc_new(rb_cProc, TRUE);
}
load(filename, wrap=false) → true
加载并执行文件filename中的Ruby程序。如果文件名不解析为绝对路径,则在文件列表中的库目录中搜索该文件$:
。如果可选的wrap参数是true
,则加载的脚本将在匿名模块下执行,以保护调用程序的全局名称空间。在任何情况下,加载文件中的任何本地变量都不会传播到加载环境。
static VALUE
rb_f_load(int argc, VALUE *argv)
{
VALUE fname, wrap, path, orig_fname;
rb_scan_args(argc, argv, "11", &fname, &wrap);
orig_fname = rb_get_path_check_to_string(fname, rb_safe_level());
fname = rb_str_encode_ospath(orig_fname);
RUBY_DTRACE_HOOK(LOAD_ENTRY, RSTRING_PTR(orig_fname));
path = rb_find_file(fname);
if (!path) {
if (!rb_file_load_ok(RSTRING_PTR(fname)))
load_failed(orig_fname);
path = fname;
}
rb_load_internal(path, RTEST(wrap));
RUBY_DTRACE_HOOK(LOAD_RETURN, RSTRING_PTR(orig_fname));
return Qtrue;
}
local_variables → array
返回当前局部变量的名称。
fred = 1
for i in 1..10
# ...
end
local_variables #=> [:fred, :i]
static VALUE
rb_f_local_variables(void)
{
struct local_var_list vars;
rb_execution_context_t *ec = GET_EC();
rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp));
unsigned int i;
local_var_list_init(&vars);
while (cfp) {
if (cfp->iseq) {
for (i = 0; i < cfp->iseq->body->local_table_size; i++) {
local_var_list_add(&vars, cfp->iseq->body->local_table[i]);
}
}
if (!VM_ENV_LOCAL_P(cfp->ep)) {
/* block */
const VALUE *ep = VM_CF_PREV_EP(cfp);
if (vm_collect_local_variables_in_heap(ep, &vars)) {
break;
}
else {
while (cfp->ep != ep) {
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
}
}
}
else {
break;
}
}
return local_var_list_finish(&vars);
}
loop { block }
loop → an_enumerator
重复执行该块。
如果没有给出块,则返回一个枚举器。
loop do
print "Input: "
line = gets
break if !line or line =~ /^qQ/
# ...
end
块中引发的StopIteration打破循环。在这种情况下,循环返回存储在异常中的“result”值。
enum = Enumerator.new { |y|
y << "one"
y << "two"
:ok
}
result = loop {
puts enum.next
} #=> :ok
static VALUE
rb_f_loop(VALUE self)
{
RETURN_SIZED_ENUMERATOR(self, 0, 0, rb_f_loop_size);
return rb_rescue2(loop_i, (VALUE)0, loop_stop, (VALUE)0, rb_eStopIteration, (VALUE)0);
}
open(path [, mode [, perm]] [, opt]) → io or nil
open(path [, mode [, perm]] [, opt]) {|io| block } → obj
创建连接到给定流,文件或子流程的IO对象。
如果path
不以管道字符(|
)开头,则将其视为要使用指定模式打开的文件的名称(默认为“r”)。
该mode
字符串可以是字符串,也可以是整数。如果它是一个整数,它必须是按位或开放(2)标志,例如File :: RDWR或File :: EXCL。如果是字符串,则为“fmode”,“fmode:ext_enc”或“fmode:ext_enc:int_enc”。
有关字符串指令的完整文档,请参阅IO.new的文档mode
。
如果正在创建文件,则可以使用该perm
参数设置其初始权限 。有关权限的描述,请参见File.new和open(2)和chmod(2)手册页。
如果指定了一个块,它将以IO对象作为参数进行调用,并且当块终止时IO将自动关闭。该调用返回该块的值。
如果path
以管道字符("|"
)开头,则会创建一个子进程,并通过一对管道连接到调用者。返回的IO对象可用于写入标准输入并从此子流程的标准输出中读取。
如果管道后面的命令是单个减号("|-"
),则Ruby分支,并且此子进程连接到父级。如果该命令不是"-"
,则该子进程运行该命令。
当子进程是Ruby(通过打开"|-"
)时, open
调用返回nil
。如果某个块与公开呼叫相关联,则该块将运行两次 - 一次在父级,一次在子级。
block参数将是父级和子级中的IO对象nil
。父IO
对象将连接到孩子的$ stdin和$ stdout。子程序将在程序段结尾处终止。
示例:
从“testfile”中读取:
open("testfile") do |f|
print f.gets
end
生成:
This is line one
打开一个子进程并读取其输出:
cmd = open("|date")
print cmd.gets
cmd.close
生成:
Wed Apr 9 08:56:31 CDT 2003
打开运行相同Ruby程序的子进程:
f = open("|-", "w+")
if f.nil?
puts "in Child"
exit
else
puts "Got: #{f.gets}"
end
生成:
Got: in Child
使用块打开子进程以接收IO对象:
open "|-" do |f|
if f then
# parent process
puts "Got: #{f.gets}"
else
# child process
puts "in Child"
end
end
生成:
Got: in Child
static VALUE
rb_f_open(int argc, VALUE *argv)
{
ID to_open = 0;
int redirect = FALSE;
if (argc >= 1) {
CONST_ID(to_open, "to_open");
if (rb_respond_to(argv[0], to_open)) {
redirect = TRUE;
}
else {
VALUE tmp = argv[0];
FilePathValue(tmp);
if (NIL_P(tmp)) {
redirect = TRUE;
}
else {
VALUE cmd = check_pipe_command(tmp);
if (!NIL_P(cmd)) {
argv[0] = cmd;
return rb_io_s_popen(argc, argv, rb_cIO);
}
}
}
}
if (redirect) {
VALUE io = rb_funcallv(argv[0], to_open, argc-1, argv+1);
if (rb_block_given_p()) {
return rb_ensure(rb_yield, io, io_close, io);
}
return io;
}
return rb_io_s_open(argc, argv, rb_cFile);
}
p(obj) → obj
p(obj1, obj2, ...) → [obj, ...]
p() → nil
对于每个对象,直接写入obj。inspect
然后是程序标准输出的换行符。
S = Struct.new(:name, :state)
s = S['dave', 'TX']
p s
生成:
#<S name="dave", state="TX">
static VALUE
rb_f_p(int argc, VALUE *argv, VALUE self)
{
struct rb_f_p_arg arg;
arg.argc = argc;
arg.argv = argv;
return rb_uninterruptible(rb_f_p_internal, (VALUE)&arg);
}
print(obj, ...) → nil
依次打印每个对象$stdout
。如果输出字段分隔符($,
)不是nil
,则其内容将出现在每个字段之间。如果输出记录separator($\
)不是nil
,它将被追加到输出。如果没有参数,打印$_
。通过调用它们的to_s
方法来转换不是字符串的对象。
print "cat", [1,2,3], 99, "\n"
$, = ", "
$\ = "\n"
print "cat", [1,2,3], 99
生成:
cat12399
cat, 1, 2, 3, 99
static VALUE
rb_f_print(int argc, const VALUE *argv)
{
rb_io_print(argc, argv, rb_stdout);
return Qnil;
}
printf(io, string [, obj ... ]) → nil
printf(string [, obj ... ]) → nil
相当于:
io.write(sprintf(string, obj, ...))
或者
$stdout.write(sprintf(string, obj, ...))
static VALUE
rb_f_printf(int argc, VALUE *argv)
{
VALUE out;
if (argc == 0) return Qnil;
if (RB_TYPE_P(argv[0], T_STRING)) {
out = rb_stdout;
}
else {
out = argv[0];
argv++;
argc--;
}
rb_io_write(out, rb_f_sprintf(argc, argv));
return Qnil;
}
proc { |...| block } → a_proc
相当于 Proc.new
。
VALUE
rb_block_proc(void)
{
return proc_new(rb_cProc, FALSE);
}
putc(int) → int
相当于:
$stdout.putc(int)
有关多字节字符的重要信息,请参阅IO#putc文档。
static VALUE
rb_f_putc(VALUE recv, VALUE ch)
{
if (recv == rb_stdout) {
return rb_io_putc(recv, ch);
}
return rb_funcallv(rb_stdout, rb_intern("putc"), 1, &ch);
}
puts(obj, ...) → nil
相当于
$stdout.puts(obj, ...)
static VALUE
rb_f_puts(int argc, VALUE *argv, VALUE recv)
{
if (recv == rb_stdout) {
return rb_io_puts(argc, argv, recv);
}
return rb_funcallv(rb_stdout, rb_intern("puts"), argc, argv);
}
raise
raise(string)
raise(exception [, string [, array]])
不带任何参数,引发异常的$!
或提出了RuntimeError
,如果$!
是nil
。用单个String
参数,将RuntimeError
字符串作为消息引发。否则,第一个参数应该是Exception
类的名称(或Exception
发送exception
消息时返回对象的对象)。可选的第二个参数设置与异常关联的消息,第三个参数是一个回调信息数组。例外被块的rescue
条款捕获begin...end
。
raise "Failed to create socket"
raise ArgumentError, "No parameters", caller
static VALUE
rb_f_raise(int argc, VALUE *argv)
{
VALUE err;
VALUE opts[raise_max_opt], *const cause = &opts[raise_opt_cause];
argc = extract_raise_opts(argc, argv, opts);
if (argc == 0) {
if (*cause != Qundef) {
rb_raise(rb_eArgError, "only cause is given with no arguments");
}
err = get_errinfo();
if (!NIL_P(err)) {
argc = 1;
argv = &err;
}
}
rb_raise_jump(rb_make_exception(argc, argv), *cause);
UNREACHABLE;
}
rand(max=0) → number
如果没有参数调用,或者如果max.to_i.abs == 0
rand返回0.0到1.0之间的伪随机浮点数,包括0.0和不包括1.0。
rand #=> 0.2725926052826416
当max.abs
大于或等于1时,rand
返回大于或等于0且小于的伪随机整数max.to_i.abs
。
rand(100) #=> 12
当max
是Range, rand
返回一个随机数,其中range.member?(number)== true。
max
允许使用负值或浮点值,但可能会给出令人惊讶的结果。
rand(-100) # => 87
rand(-0.5) # => 0.8130921818028143
rand(1.9) # equivalent to rand(1), which is always 0
#srand可用于确保随机数序列在程序的不同运行之间可重现。
另见Random#rand。
static VALUE
rb_f_rand(int argc, VALUE *argv, VALUE obj)
{
VALUE vmax;
rb_random_t *rnd = rand_start(&default_rand);
if (rb_check_arity(argc, 0, 1) && !NIL_P(vmax = argv[0])) {
VALUE v = rand_range(Qnil, rnd, vmax);
if (v != Qfalse) return v;
vmax = rb_to_int(vmax);
if (vmax != INT2FIX(0)) {
v = rand_int(Qnil, rnd, vmax, 0);
if (!NIL_P(v)) return v;
}
}
return DBL2NUM(genrand_real(&rnd->mt));
}
readline(sep=$/) → string
readline(limit) → string
readline(sep, limit) → string
相当于Kernel::gets
,除了在文件末尾readline
提高EOFError
。
static VALUE
rb_f_readline(int argc, VALUE *argv, VALUE recv)
{
if (recv == argf) {
return argf_readline(argc, argv, argf);
}
return rb_funcallv(argf, rb_intern("readline"), argc, argv);
}
readlines(sep=$/) → array
readlines(limit) → array
readlines(sep, limit) → array
返回一个数组,其中包含通过调用返回的直到文件结尾的行。Kernel.gets(sep)
static VALUE
rb_f_readlines(int argc, VALUE *argv, VALUE recv)
{
if (recv == argf) {
return argf_readlines(argc, argv, argf);
}
return rb_funcallv(argf, rb_intern("readlines"), argc, argv);
}
require(name) → true or false
加载给定的name
,如果成功返回true
,并且false
该特征已经加载。
如果文件名不解析为绝对路径,将在$LOAD_PATH
($:
)中列出的目录中搜索。
如果文件名的扩展名为“.rb”,则将其作为源文件加载; 如果扩展名为“.so”,“.o”或“.dll”,或者当前平台上的默认共享库扩展名,则Ruby会将共享库作为Ruby扩展名加载。否则,Ruby会尝试将“.rb”,“.so”等添加到名称中直到找到。如果找不到名为的文件,则会引发LoadError。
对于Ruby扩展,给出的文件名可以使用任何共享库扩展。例如,在Linux上,套接字扩展名是“socket.so”, require 'socket.dll'
并将加载套接字扩展名。
加载文件的绝对路径被添加到 $LOADED_FEATURES
($"
)。如果路径已经出现,文件将不会再次加载$"
。例如,require 'a'; require './a'
不会a.rb
再次加载。
require "my-library.rb"
require "db-driver"
加载的源文件中的任何常量或全局变量都将在调用程序的全局名称空间中可用。但是,局部变量不会传播到加载环境。
VALUE
rb_f_require(VALUE obj, VALUE fname)
{
return rb_require_safe(fname, rb_safe_level());
}
require_relative(string) → true or false
Ruby尝试加载相对于所需文件路径的名为string的库。如果无法确定文件的路径,则会引发LoadError。如果加载文件则返回true
,否则返回false。
VALUE
rb_f_require_relative(VALUE obj, VALUE fname)
{
VALUE base = rb_current_realfilepath();
if (NIL_P(base)) {
rb_loaderror("cannot infer basepath");
}
base = rb_file_dirname(base);
return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
}
select(read_array [, write_array [, error_array [, timeout]]]) → array or nil
选择(2)系统呼叫。它监视给定的IO
对象数组,等待一个或多个IO
对象准备好读取,准备好写入并分别具有未决异常,并返回一个包含这些IO 对象数组的数组。nil
如果给定了可选的超时值并且超时 秒内没有IO
对象准备就绪,它将返回。
IO.select
偷看IO
对象的缓冲区以测试可读性。如果IO
缓冲区不是空的, IO.select
立即通知可读性。这个“窥视”只发生在IO
物体上。它不会发生类似IO的对象,例如OpenSSL :: SSL :: SSLSocket。
用最好的方式IO.select
是非阻塞的方法,如后调用它read_nonblock
,write_nonblock
等。该方法提高其通过扩展一个异常 IO::WaitReadable
或IO::WaitWritable
。模块通知呼叫方应该如何等待IO.select
。如果 IO::WaitReadable
提出,主叫方应该等待阅读。如果IO::WaitWritable
被提出,则调用者应该等待写入。
所以,readpartial
可以使用read_nonblock
和模拟阻塞read() IO.select
,如下所示:
begin
result = io_like.read_nonblock(maxlen)
rescue IO::WaitReadable
IO.select([io_like])
retry
rescue IO::WaitWritable
IO.select(nil, [io_like])
retry
end
尤其是,非阻塞方法的组合,并且 IO.select
对于IO
类似的对象比较喜欢OpenSSL::SSL::SSLSocket
。它有to_io
返回基础IO
对象的方法。IO.select
调用 to_io
获取文件描述符以等待。
这意味着通知的IO.select
可读性并不意味着可读性OpenSSL::SSL::SSLSocket
。
最可能的情况是OpenSSL::SSL::SSLSocket
缓冲一些数据。IO.select
没有看到缓冲区。所以IO.select
可以阻挡何时 OpenSSL::SSL::SSLSocket#readpartial
不阻挡。
然而,存在几个更复杂的情况。
SSL是一个记录序列的协议。该记录由多个字节组成。所以,SSL的远程端发送一个部分记录, IO.select
通知可读性但 OpenSSL::SSL::SSLSocket
不能解密一个字节,并OpenSSL::SSL::SSLSocket#readpartial
会阻塞。
另外,远程端可以请求SSL重新协商,强制本地SSL引擎写入一些数据。这意味着OpenSSL::SSL::SSLSocket#readpartial
可能会调用 write
系统调用,并且可能会阻塞。在这种情况下, OpenSSL::SSL::SSLSocket#read_nonblock
引发IO :: WaitWritable而不是阻塞。因此,调用者应该等待上述例子的可写性。
非阻塞方法的组合,IO.select
当流从多个流中读取时,对于诸如tty,管道套接字套接字等流也很有用。
最后,Linux内核开发人员不保证select(2)的可读性意味着即使对于单个进程也可以读取(2)。请参阅GNU / Linux系统上的选择(2)手册。
IO.select
在IO#readpartial
平常工作之前调用。但它不是最好的使用方法 IO.select
。
select(2)通知的可写性不显示可写入多少字节。IO#write
方法阻塞,直到写入完整的字符串。所以,IO#write(two or more bytes)
可写性通知后可以阻塞IO.select
。IO#write_nonblock
需要避免阻塞。
阻塞写(write
)可以使用模拟 write_nonblock
和IO.select
如下:IO :: WaitReadable也应该救在SSL重新协商OpenSSL::SSL::SSLSocket
。
while 0 < string.bytesize
begin
written = io_like.write_nonblock(string)
rescue IO::WaitReadable
IO.select([io_like])
retry
rescue IO::WaitWritable
IO.select(nil, [io_like])
retry
end
string = string.byteslice(written..-1)
end
参数
read_array
IO
等待准备读取的对象数组
write_array
IO
等待准备写入的对象数组
error_array
IO
等待异常的对象数组
timeout
以秒为单位的数值
示例
rp, wp = IO.pipe
mesg = "ping "
100.times {
# IO.select follows IO#read. Not the best way to use IO.select.
rs, ws, = IO.select([rp], [wp])
if r = rs[0]
ret = r.read(5)
print ret
case ret
when /ping/
mesg = "pong\n"
when /pong/
mesg = "ping "
end
end
if w = ws[0]
w.write(mesg)
end
}
生成:
ping pong
ping pong
ping pong
(snipped)
ping
static VALUE
rb_f_select(int argc, VALUE *argv, VALUE obj)
{
VALUE timeout;
struct select_args args;
struct timeval timerec;
int i;
rb_scan_args(argc, argv, "13", &args.read, &args.write, &args.except, &timeout);
if (NIL_P(timeout)) {
args.timeout = 0;
}
else {
timerec = rb_time_interval(timeout);
args.timeout = &timerec;
}
for (i = 0; i < numberof(args.fdsets); ++i)
rb_fd_init(&args.fdsets[i]);
return rb_ensure(select_call, (VALUE)&args, select_end, (VALUE)&args);
}
et_trace_func(proc) → proc
set_trace_func(nil) → nil
建立proc作为跟踪处理程序,或者如果参数是禁用跟踪nil
。
注意:此方法已过时,请改用TracePoint。
proc最多需要六个参数:
- 一个事件名称
- 一个文件名
- 一个行号
- 一个对象 ID
- 一个绑定
- 一个classproc的名称
proc在事件发生时被调用。
活动有:
c-call
调用一个C语言例程
c-return
从C语言例程返回
call
调用Ruby方法
class
启动一个类或模块定义
end
完成一个类或模块的定义
line
在新行上执行代码
raise
引发异常
return
从Ruby方法返回
跟踪在proc的上下文中被禁用。
class Test
def test
a = 1
b = 2
end
end
set_trace_func proc { |event, file, line, id, binding, classname|
printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname
}
t = Test.new
t.test
line prog.rb:11 false
c-call prog.rb:11 new Class
c-call prog.rb:11 initialize Object
c-return prog.rb:11 initialize Object
c-return prog.rb:11 new Class
line prog.rb:12 false
call prog.rb:2 test Test
line prog.rb:3 test Test
line prog.rb:4 test Test
return prog.rb:4 test Test
sleep([duration]) → integer
暂停当前线程持续时间秒(可能是任何数字,包括Float
小数秒)。返回睡眠的实际秒数(舍入),可能小于另一个线程调用时所要求的秒数Thread#run
。sleep()会在没有参数的情况下调用,将永远睡眠。
Time.new #=> 2008-03-08 19:56:19 +0900
sleep 1.2 #=> 1
Time.new #=> 2008-03-08 19:56:20 +0900
sleep 1.9 #=> 2
Time.new #=> 2008-03-08 19:56:22 +0900
static VALUE
rb_f_sleep(int argc, VALUE *argv)
{
time_t beg, end;
beg = time(0);
if (argc == 0) {
rb_thread_sleep_forever();
}
else {
rb_check_arity(argc, 0, 1);
rb_thread_wait_for(rb_time_interval(argv[0]));
}
end = time(0) - beg;
return INT2FIX(end);
}
spawn([env,] command... [,options]) → pidclick to toggle source
spawn([env,] command... [,options]) → pid
spawn执行指定的命令并返回它的pid。
pid = spawn("tar xf ruby-2.0.0-p195.tar.bz2")
Process.wait pid
pid = spawn(RbConfig.ruby, "-eputs'Hello, world!'")
Process.wait pid
此方法与#system类似, 但不等待命令完成。
父母程序应该Process.wait
用来收集其子女的终止状态或用于Process.detach
注册他们的状态不感兴趣; 否则,操作系统可能会累积僵尸进程。
spawn有很多选项来指定进程属性:
env: hash
name => val : set the environment variable
name => nil : unset the environment variable
the keys and the values except for +nil+ must be strings.
command...:
commandline : command line string which is passed to the standard shell
cmdname, arg1, ... : command name and one or more arguments (This form does not use the shell. See below for caveats.)
[cmdname, argv0], arg1, ... : command name, argv[0] and zero or more arguments (no shell)
options: hash
clearing environment variables:
:unsetenv_others => true : clear environment variables except specified by env
:unsetenv_others => false : don't clear (default)
process group:
:pgroup => true or 0 : make a new process group
:pgroup => pgid : join the specified process group
:pgroup => nil : don't change the process group (default)
create new process group: Windows only
:new_pgroup => true : the new process is the root process of a new process group
:new_pgroup => false : don't create a new process group (default)
resource limit: resourcename is core, cpu, data, etc. See Process.setrlimit.
:rlimit_resourcename => limit
:rlimit_resourcename => [cur_limit, max_limit]
umask:
:umask => int
redirection:
key:
FD : single file descriptor in child process
[FD, FD, ...] : multiple file descriptor in child process
value:
FD : redirect to the file descriptor in parent process
string : redirect to file with open(string, "r" or "w")
[string] : redirect to file with open(string, File::RDONLY)
[string, open_mode] : redirect to file with open(string, open_mode, 0644)
[string, open_mode, perm] : redirect to file with open(string, open_mode, perm)
[:child, FD] : redirect to the redirected file descriptor
:close : close the file descriptor in child process
FD is one of follows
:in : the file descriptor 0 which is the standard input
:out : the file descriptor 1 which is the standard output
:err : the file descriptor 2 which is the standard error
integer : the file descriptor of specified the integer
io : the file descriptor specified as io.fileno
file descriptor inheritance: close non-redirected non-standard fds (3, 4, 5, ...) or not
:close_others => true : don't inherit
current directory:
:chdir => str
The 'cmdname, arg1, ...' form does not use the shell. However,
on different OSes, different things are provided as built-in
commands. An example of this is 'echo', which is a built-in
on Windows, but is a normal program on Linux and Mac OS X.
This means that `Process.spawn 'echo', '%Path%'` will display
the contents of the `%Path%` environment variable on Windows,
but `Process.spawn 'echo', '$PATH'` prints the literal '$PATH'.
如果给出散列env
,则在子进程中env
之前更新环境exec(2)
。如果一对中env
的值为零,则该变量将被删除。
# set FOO as BAR and unset BAZ.
pid = spawn({"FOO"=>"BAR", "BAZ"=>nil}, command)
如果options
指定了散列,则指定进程组,为子进程创建新进程组,资源限制,当前目录,umask并重定向。另外,可以指定清除环境变量。
在:unsetenv_others
关键options
则表示清除环境变量,比规定的其他env
。
pid = spawn(command, :unsetenv_others=>true) # no environment variable
pid = spawn({"FOO"=>"BAR"}, command, :unsetenv_others=>true) # FOO only
:pgroup
在键options
指定的处理组。相应的值应该为true,零,一个正整数或零。真实且零为原因的过程将成为新流程组的流程负责人。非零的正整数会导致进程加入提供的进程组。缺省值nil使进程保留在同一个进程组中。
pid = spawn(command, :pgroup=>true) # process leader
pid = spawn(command, :pgroup=>10) # belongs to the process group 10
在:new_pgroup
关键options
指定传递CREATE_NEW_PROCESS_GROUP
标志,CreateProcessW()
那就是Windows API的。该选项仅适用于Windows。true表示新进程是新进程组的根进程。新进程禁用了CTRL + C。这个标志对于Process.kill(:SIGINT, pid)
子进程是必需的。:默认情况下,new_pgroup为false。
pid = spawn(command, :new_pgroup=>true) # new process group
pid = spawn(command, :new_pgroup=>false) # same process group
该:rlimit_
FOO键指定的资源限制。foo应该是如下的资源类型之一core
。相应的值应该是一个整数或一个有一个或两个整数的数组:与Process.setrlimit的cur_limit和max_limit参数相同。
cur, max = Process.getrlimit(:CORE)
pid = spawn(command, :rlimit_core=>[0,max]) # disable core temporary.
pid = spawn(command, :rlimit_core=>max) # enable core dump
pid = spawn(command, :rlimit_core=>0) # never dump core.
在:umask
关键options
指定的umask。
pid = spawn(command, :umask=>077)
:in, :out, :err, integer, IO和array key数组键指定重定向。重定向映射子进程中的文件描述符。
例如,stderr可以合并到stdout中,如下所示:
pid = spawn(command, :err=>:out)
pid = spawn(command, 2=>1)
pid = spawn(command, STDERR=>:out)
pid = spawn(command, STDERR=>STDOUT)
散列键指定由子启动的子进程中的文件描述符 spawn
。:err,2和STDERR指定标准错误流(stderr)。
散列值指定调用的父进程中的文件描述符spawn
。:out,1和STDOUT指定标准输出流(stdout)。
在上面的例子中,没有指定子进程中的标准输出。所以它是从父进程继承的。
标准输入流(stdin)可以通过:in,0和STDIN指定。
文件名可以被指定为散列值。
pid = spawn(command, :in=>"/dev/null") # read mode
pid = spawn(command, :out=>"/dev/null") # write mode
pid = spawn(command, :err=>"log") # write mode
pid = spawn(command, [:out, :err]=>"/dev/null") # write mode
pid = spawn(command, 3=>"/dev/null") # read mode
对于stdout和stderr(以及它们的组合),它在写入模式下打开。否则使用读取模式。
为了显式指定标志和文件创建权限,可以使用数组。
pid = spawn(command, :in=>["file"]) # read mode is assumed
pid = spawn(command, :in=>["file", "r"])
pid = spawn(command, :out=>["log", "w"]) # 0644 assumed
pid = spawn(command, :out=>["log", "w", 0600])
pid = spawn(command, :out=>["log", File::WRONLY|File::EXCL|File::CREAT, 0600])
该数组指定一个文件名,标志和权限。这些标志可以是一个字符串或一个整数。如果省略标志或零,则假定File :: RDONLY。权限应该是一个整数。如果权限被忽略或零,则假定为0644。
如果将IO和整数数组指定为散列键,则所有元素都将被重定向。
# stdout and stderr is redirected to log file.
# The file "log" is opened just once.
pid = spawn(command, [:out, :err]=>["log", "w"])
合并多个文件描述符的另一种方式是[:child,fd]。[:child,fd]表示子进程中的文件描述符。这与fd不同。例如,:err =>:out意味着将子stderr重定向到父标准输出。但是:err => [:child,:out]意味着将子标准错误重定向到子标准输出。如果stdout在子进程中被重定向,它们会有所不同,如下所示。
# stdout and stderr is redirected to log file.
# The file "log" is opened just once.
pid = spawn(command, :out=>["log", "w"], :err=>[:child, :out])
[:child, :out]可用于将stderr合并到IO.popen中的stdout。在这种情况下,IO.popen将stdout重定向到子进程中的管道,[:child, :out]引用重定向的stdout。
io = IO.popen(["sh", "-c", "echo out; echo err >&2", :err=>[:child, :out]])
p io.read #=> "out\nerr\n"
在:chdir
关键options
指定当前目录。
pid = spawn(command, :chdir=>"/var/tmp")
spawn默认关闭所有非标准的未指定描述符。“标准”描述符为0,1和2.此行为由close_others选项指定。:close_others不会影响仅在以下情况下关闭的标准描述符:close明确指定。
pid = spawn(command, :close_others=>true) # close 3,4,5,... (default)
pid = spawn(command, :close_others=>false) # don't close 3,4,5,...
:spawn和IO.popen默认为close_others。
请注意,无论close_others选项如何,已关闭执行close-on-exec标志的fds都会关闭。
# similar to r = IO.popen(command)
r, w = IO.pipe
pid = spawn(command, :out=>w) # r, w is closed in the child process.
w.close
:close被指定为散列值来单独关闭fd。
f = open(foo)
system(command, f=>:close) # don't inherit f.
如果需要继承一个文件描述符,可以使用io => io。
# valgrind has --log-fd option for log destination.
# log_w=>log_w indicates log_w.fileno inherits to child process.
log_r, log_w = IO.pipe
pid = spawn("valgrind", "--log-fd=#{log_w.fileno}", "echo", "a", log_w=>log_w)
log_w.close
p log_r.read
它也可以交换文件描述符。
pid = spawn(command, :out=>:err, :err=>:out)
散列键指定子进程中的文件描述符。散列值指定父进程中的文件描述符。所以上面指定交换stdout和stderr。在内部,spawn
使用额外的文件描述符来解决这种循环文件描述符映射。
请参阅Kernel.exec
标准外壳。
static VALUE
rb_f_spawn(int argc, VALUE *argv)
{
rb_pid_t pid;
char errmsg[CHILD_ERRMSG_BUFLEN] = { '\0' };
VALUE execarg_obj, fail_str;
struct rb_execarg *eargp;
execarg_obj = rb_execarg_new(argc, argv, TRUE);
eargp = rb_execarg_get(execarg_obj);
fail_str = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;
pid = rb_execarg_spawn(execarg_obj, errmsg, sizeof(errmsg));
if (pid == -1) {
int err = errno;
rb_exec_fail(eargp, err, errmsg);
RB_GC_GUARD(execarg_obj);
rb_syserr_fail_str(err, fail_str);
}
#if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV)
return PIDT2NUM(pid);
#else
return Qnil;
#endif
}
sprintf(format_string [, arguments...] ) → string
返回将format_string应用于任何其他参数所产生的字符串。在格式字符串中,格式序列以外的任何字符都将被复制到结果中。
格式序列的语法如下。
%[flags][width][.precision]type
一个格式序列由一个百分号组成,后跟可选的标志,宽度和精度指示符,然后以字段类型字符结尾。字段类型控制相应sprintf
参数如何 解释,而标志修改解释。
字段类型字符是:
Field | Integer Format
------+--------------------------------------------------------------
b | Convert argument as a binary number.
| Negative numbers will be displayed as a two's complement
| prefixed with `..1'.
B | Equivalent to `b', but uses an uppercase 0B for prefix
| in the alternative format by #.
d | Convert argument as a decimal number.
i | Identical to `d'.
o | Convert argument as an octal number.
| Negative numbers will be displayed as a two's complement
| prefixed with `..7'.
u | Identical to `d'.
x | Convert argument as a hexadecimal number.
| Negative numbers will be displayed as a two's complement
| prefixed with `..f' (representing an infinite string of
| leading 'ff's).
X | Equivalent to `x', but uses uppercase letters.
Field | Float Format
------+--------------------------------------------------------------
e | Convert floating point argument into exponential notation
| with one digit before the decimal point as [-]d.dddddde[+-]dd.
| The precision specifies the number of digits after the decimal
| point (defaulting to six).
E | Equivalent to `e', but uses an uppercase E to indicate
| the exponent.
f | Convert floating point argument as [-]ddd.dddddd,
| where the precision specifies the number of digits after
| the decimal point.
g | Convert a floating point number using exponential form
| if the exponent is less than -4 or greater than or
| equal to the precision, or in dd.dddd form otherwise.
| The precision specifies the number of significant digits.
G | Equivalent to `g', but use an uppercase `E' in exponent form.
a | Convert floating point argument as [-]0xh.hhhhp[+-]dd,
| which is consisted from optional sign, "0x", fraction part
| as hexadecimal, "p", and exponential part as decimal.
A | Equivalent to `a', but use uppercase `X' and `P'.
Field | Other Format
------+--------------------------------------------------------------
c | Argument is the numeric code for a single character or
| a single character string itself.
p | The valuing of argument.inspect.
s | Argument is a string to be substituted. If the format
| sequence contains a precision, at most that many characters
| will be copied.
% | A percent sign itself will be displayed. No argument taken.
标志修改格式的行为。标志字符是:
Flag | Applies to | Meaning
---------+---------------+-----------------------------------------
space | bBdiouxX | Leave a space at the start of
| aAeEfgG | non-negative numbers.
| (numeric fmt) | For `o', `x', `X', `b' and `B', use
| | a minus sign with absolute value for
| | negative values.
---------+---------------+-----------------------------------------
(digit)$ | all | Specifies the absolute argument number
| | for this field. Absolute and relative
| | argument numbers cannot be mixed in a
| | sprintf string.
---------+---------------+-----------------------------------------
# | bBoxX | Use an alternative format.
| aAeEfgG | For the conversions `o', increase the precision
| | until the first digit will be `0' if
| | it is not formatted as complements.
| | For the conversions `x', `X', `b' and `B'
| | on non-zero, prefix the result with ``0x'',
| | ``0X'', ``0b'' and ``0B'', respectively.
| | For `a', `A', `e', `E', `f', `g', and 'G',
| | force a decimal point to be added,
| | even if no digits follow.
| | For `g' and 'G', do not remove trailing zeros.
---------+---------------+-----------------------------------------
+ | bBdiouxX | Add a leading plus sign to non-negative
| aAeEfgG | numbers.
| (numeric fmt) | For `o', `x', `X', `b' and `B', use
| | a minus sign with absolute value for
| | negative values.
---------+---------------+-----------------------------------------
- | all | Left-justify the result of this conversion.
---------+---------------+-----------------------------------------
0 (zero) | bBdiouxX | Pad with zeros, not spaces.
| aAeEfgG | For `o', `x', `X', `b' and `B', radix-1
| (numeric fmt) | is used for negative numbers formatted as
| | complements.
---------+---------------+-----------------------------------------
* | all | Use the next argument as the field width.
| | If negative, left-justify the result. If the
| | asterisk is followed by a number and a dollar
| | sign, use the indicated argument as the width.
标志的例子:
# `+' and space flag specifies the sign of non-negative numbers.
sprintf("%d", 123) #=> "123"
sprintf("%+d", 123) #=> "+123"
sprintf("% d", 123) #=> " 123"
# `#' flag for `o' increases number of digits to show `0'.
# `+' and space flag changes format of negative numbers.
sprintf("%o", 123) #=> "173"
sprintf("%#o", 123) #=> "0173"
sprintf("%+o", -123) #=> "-173"
sprintf("%o", -123) #=> "..7605"
sprintf("%#o", -123) #=> "..7605"
# `#' flag for `x' add a prefix `0x' for non-zero numbers.
# `+' and space flag disables complements for negative numbers.
sprintf("%x", 123) #=> "7b"
sprintf("%#x", 123) #=> "0x7b"
sprintf("%+x", -123) #=> "-7b"
sprintf("%x", -123) #=> "..f85"
sprintf("%#x", -123) #=> "0x..f85"
sprintf("%#x", 0) #=> "0"
# `#' for `X' uses the prefix `0X'.
sprintf("%X", 123) #=> "7B"
sprintf("%#X", 123) #=> "0X7B"
# `#' flag for `b' add a prefix `0b' for non-zero numbers.
# `+' and space flag disables complements for negative numbers.
sprintf("%b", 123) #=> "1111011"
sprintf("%#b", 123) #=> "0b1111011"
sprintf("%+b", -123) #=> "-1111011"
sprintf("%b", -123) #=> "..10000101"
sprintf("%#b", -123) #=> "0b..10000101"
sprintf("%#b", 0) #=> "0"
# `#' for `B' uses the prefix `0B'.
sprintf("%B", 123) #=> "1111011"
sprintf("%#B", 123) #=> "0B1111011"
# `#' for `e' forces to show the decimal point.
sprintf("%.0e", 1) #=> "1e+00"
sprintf("%#.0e", 1) #=> "1.e+00"
# `#' for `f' forces to show the decimal point.
sprintf("%.0f", 1234) #=> "1234"
sprintf("%#.0f", 1234) #=> "1234."
# `#' for `g' forces to show the decimal point.
# It also disables stripping lowest zeros.
sprintf("%g", 123.4) #=> "123.4"
sprintf("%#g", 123.4) #=> "123.400"
sprintf("%g", 123456) #=> "123456"
sprintf("%#g", 123456) #=> "123456."
字段宽度是一个可选的整数,随后可以选择一个句点和一个精度。宽度指定将写入该字段结果的最小字符数。
宽度示例:
# padding is done by spaces, width=20
# 0 or radix-1. <------------------>
sprintf("%20d", 123) #=> " 123"
sprintf("%+20d", 123) #=> " +123"
sprintf("%020d", 123) #=> "00000000000000000123"
sprintf("%+020d", 123) #=> "+0000000000000000123"
sprintf("% 020d", 123) #=> " 0000000000000000123"
sprintf("%-20d", 123) #=> "123 "
sprintf("%-+20d", 123) #=> "+123 "
sprintf("%- 20d", 123) #=> " 123 "
sprintf("%020x", -123) #=> "..ffffffffffffffff85"
对于数字字段,精度控制显示的小数位数。对于字符串字段,精度决定了要从字符串复制的最大字符数。(因此,格式序列 %10.10s
总是对结果贡献正好十个字符。)
精度示例:
# precision for `d', 'o', 'x' and 'b' is
# minimum number of digits <------>
sprintf("%20.8d", 123) #=> " 00000123"
sprintf("%20.8o", 123) #=> " 00000173"
sprintf("%20.8x", 123) #=> " 0000007b"
sprintf("%20.8b", 123) #=> " 01111011"
sprintf("%20.8d", -123) #=> " -00000123"
sprintf("%20.8o", -123) #=> " ..777605"
sprintf("%20.8x", -123) #=> " ..ffff85"
sprintf("%20.8b", -11) #=> " ..110101"
# "0x" and "0b" for `#x' and `#b' is not counted for
# precision but "0" for `#o' is counted. <------>
sprintf("%#20.8d", 123) #=> " 00000123"
sprintf("%#20.8o", 123) #=> " 00000173"
sprintf("%#20.8x", 123) #=> " 0x0000007b"
sprintf("%#20.8b", 123) #=> " 0b01111011"
sprintf("%#20.8d", -123) #=> " -00000123"
sprintf("%#20.8o", -123) #=> " ..777605"
sprintf("%#20.8x", -123) #=> " 0x..ffff85"
sprintf("%#20.8b", -11) #=> " 0b..110101"
# precision for `e' is number of
# digits after the decimal point <------>
sprintf("%20.8e", 1234.56789) #=> " 1.23456789e+03"
# precision for `f' is number of
# digits after the decimal point <------>
sprintf("%20.8f", 1234.56789) #=> " 1234.56789000"
# precision for `g' is number of
# significant digits <------->
sprintf("%20.8g", 1234.56789) #=> " 1234.5679"
# <------->
sprintf("%20.8g", 123456789) #=> " 1.2345679e+08"
# precision for `s' is
# maximum number of characters <------>
sprintf("%20.8s", "string test") #=> " string t"
例子:
sprintf("%d %04x", 123, 123) #=> "123 007b"
sprintf("%08b '%4s'", 123, 123) #=> "01111011 ' 123'"
sprintf("%1$*2$s %2$d %1$s", "hello", 8) #=> " hello 8 hello"
sprintf("%1$*2$s %2$d", "hello", -8) #=> "hello -8"
sprintf("%+g:% g:%-g", 1.23, 1.23, 1.23) #=> "+1.23: 1.23:1.23"
sprintf("%u", -123) #=> "-123"
对于更复杂的格式,Ruby支持按名称引用。%<name>的样式使用格式样式,但%{name}样式不会。
例子:
sprintf("%<foo>d : %<bar>f", { :foo => 1, :bar => 2 })
#=> 1 : 2.000000
sprintf("%{foo}f", { :foo => 1 })
# => "1f"
VALUE
rb_f_sprintf(int argc, const VALUE *argv)
{
return rb_str_format(argc - 1, argv + 1, GETNTHARG(0));
}
srand(number = Random.new_seed) → old_seed
种子系统伪随机数生成器Random :: DEFAULT与 number
。之前的种子值被返回。
如果number
省略,则使用操作系统提供的熵源(如果可用)(Unix系统上的/ dev / urandom或Windows上的RSA加密提供程序)为发生器生成种子,然后将其与时间,进程ID和一个序列号。
srand可用于确保程序的不同运行之间可重复的伪随机数序列。通过将种子设置为已知值,可以在测试过程中确定程序的确定性。
srand 1234 # => 268519324636777531569100071560086917274
[ rand, rand ] # => [0.1915194503788923, 0.6221087710398319]
[ rand(10), rand(1000) ] # => [4, 664]
srand 1234 # => 1234
[ rand, rand ] # => [0.1915194503788923, 0.6221087710398319]
static VALUE
rb_f_srand(int argc, VALUE *argv, VALUE obj)
{
VALUE seed, old;
rb_random_t *r = &default_rand;
if (rb_check_arity(argc, 0, 1) == 0) {
seed = random_seed();
}
else {
seed = rb_to_int(argv[0]);
}
old = r->seed;
r->seed = rand_init(&r->mt, seed);
return old;
}
sub(pattern, replacement) → $_
sub(pattern) {|...| block } → $_
等同于,除了将在更换发生时更新。仅在指定-p / -n命令行选项时可用$_.sub(args)$_
。
static VALUE
rb_f_sub(int argc, VALUE *argv)
{
VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("sub"), argc, argv);
rb_lastline_set(str);
return str;
}
syscall(num [, args...]) → integer
Calls the operating system function identified by _num_ and
returns the result of the function or raises SystemCallError if
it failed.
Arguments for the function can follow _num_. They must be either
+String+ objects or +Integer+ objects. A +String+ object is passed
as a pointer to the byte sequence. An +Integer+ object is passed
as an integer whose bit size is same as a pointer.
Up to nine parameters may be passed.
The function identified by _num_ is system
dependent. On some Unix systems, the numbers may be obtained from a
header file called <code>syscall.h</code>.
syscall 4, 1, "hello\n", 6 # '4' is write(2) on our box
<em>produces:</em>
hello
Calling +syscall+ on a platform which does not have any way to
an arbitrary system function just fails with NotImplementedError.
注意
syscall
基本上是不安全和不可移植的。随意拍摄你的脚。DL(Fiddle)库是更安全和更便携式编程的首选。
static VALUE
rb_f_syscall(int argc, VALUE *argv)
{
VALUE arg[8];
#if SIZEOF_VOIDP == 8 && defined(HAVE___SYSCALL) && SIZEOF_INT != 8 /* mainly *BSD */
# define SYSCALL __syscall
# define NUM2SYSCALLID(x) NUM2LONG(x)
# define RETVAL2NUM(x) LONG2NUM(x)
# if SIZEOF_LONG == 8
long num, retval = -1;
# elif SIZEOF_LONG_LONG == 8
long long num, retval = -1;
# else
# error ---->> it is asserted that __syscall takes the first argument and returns retval in 64bit signed integer. <<----
# endif
#elif defined(__linux__)
# define SYSCALL syscall
# define NUM2SYSCALLID(x) NUM2LONG(x)
# define RETVAL2NUM(x) LONG2NUM(x)
/*
* Linux man page says, syscall(2) function prototype is below.
*
* int syscall(int number, ...);
*
* But, it's incorrect. Actual one takes and returned long. (see unistd.h)
*/
long num, retval = -1;
#else
# define SYSCALL syscall
# define NUM2SYSCALLID(x) NUM2INT(x)
# define RETVAL2NUM(x) INT2NUM(x)
int num, retval = -1;
#endif
int i;
if (RTEST(ruby_verbose)) {
rb_warning("We plan to remove a syscall function at future release. DL(Fiddle) provides safer alternative.");
}
if (argc == 0)
rb_raise(rb_eArgError, "too few arguments for syscall");
if (argc > numberof(arg))
rb_raise(rb_eArgError, "too many arguments for syscall");
num = NUM2SYSCALLID(argv[0]); ++argv;
for (i = argc - 1; i--; ) {
VALUE v = rb_check_string_type(argv[i]);
if (!NIL_P(v)) {
SafeStringValue(v);
rb_str_modify(v);
arg[i] = (VALUE)StringValueCStr(v);
}
else {
arg[i] = (VALUE)NUM2LONG(argv[i]);
}
}
switch (argc) {
case 1:
retval = SYSCALL(num);
break;
case 2:
retval = SYSCALL(num, arg[0]);
break;
case 3:
retval = SYSCALL(num, arg[0],arg[1]);
break;
case 4:
retval = SYSCALL(num, arg[0],arg[1],arg[2]);
break;
case 5:
retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3]);
break;
case 6:
retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4]);
break;
case 7:
retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5]);
break;
case 8:
retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6]);
break;
}
if (retval == -1)
rb_sys_fail(0);
return RETVAL2NUM(retval);
#undef SYSCALL
#undef NUM2SYSCALLID
#undef RETVAL2NUM
}
system([env,] command... [,options]) → true, false or nil
在子shell中执行命令...。命令...是以下形式之一。
commandline : command line string which is passed to the standard shell
cmdname, arg1, ... : command name and one or more arguments (no shell)
[cmdname, argv0], arg1, ... : command name, argv[0] and zero or more arguments (no shell)
如果命令给出零退出状态,则 返回true
非零退出状态。nil
如果命令执行失败则返回false
。错误状态可用于$?
。参数的处理方式与以前相同 Kernel.spawn
。
散列参数env和options与exec
and 相同spawn
。详情请参阅Kernel.spawn
。
system("echo *")
system("echo", "*")
生成:
config.h main.rb
*
请参阅Kernel.exec
标准外壳。
static VALUE
rb_f_system(int argc, VALUE *argv)
{
rb_pid_t pid;
int status;
#if defined(SIGCLD) && !defined(SIGCHLD)
# define SIGCHLD SIGCLD
#endif
#ifdef SIGCHLD
RETSIGTYPE (*chfunc)(int);
rb_last_status_clear();
chfunc = signal(SIGCHLD, SIG_DFL);
#endif
pid = rb_spawn_internal(argc, argv, NULL, 0);
#if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV)
if (pid > 0) {
int ret, status;
ret = rb_waitpid(pid, &status, 0);
if (ret == (rb_pid_t)-1)
rb_sys_fail("Another thread waited the process started by system().");
}
#endif
#ifdef SIGCHLD
signal(SIGCHLD, chfunc);
#endif
if (pid < 0) {
return Qnil;
}
status = PST2INT(rb_last_status_get());
if (status == EXIT_SUCCESS) return Qtrue;
return Qfalse;
}
test(cmd, file1 [, file2] ) → objclick to toggle source
使用字符cmd
执行各种测试 file1
(第一表)或上file1
和 file2
(第二个表)。
在单个文件上进行文件测试:
Cmd Returns Meaning
"A" | Time | Last access time for file1
"b" | boolean | True if file1 is a block device
"c" | boolean | True if file1 is a character device
"C" | Time | Last change time for file1
"d" | boolean | True if file1 exists and is a directory
"e" | boolean | True if file1 exists
"f" | boolean | True if file1 exists and is a regular file
"g" | boolean | True if file1 has the \CF{setgid} bit
| | set (false under NT)
"G" | boolean | True if file1 exists and has a group
| | ownership equal to the caller's group
"k" | boolean | True if file1 exists and has the sticky bit set
"l" | boolean | True if file1 exists and is a symbolic link
"M" | Time | Last modification time for file1
"o" | boolean | True if file1 exists and is owned by
| | the caller's effective uid
"O" | boolean | True if file1 exists and is owned by
| | the caller's real uid
"p" | boolean | True if file1 exists and is a fifo
"r" | boolean | True if file1 is readable by the effective
| | uid/gid of the caller
"R" | boolean | True if file is readable by the real
| | uid/gid of the caller
"s" | int/nil | If file1 has nonzero size, return the size,
| | otherwise return nil
"S" | boolean | True if file1 exists and is a socket
"u" | boolean | True if file1 has the setuid bit set
"w" | boolean | True if file1 exists and is writable by
| | the effective uid/gid
"W" | boolean | True if file1 exists and is writable by
| | the real uid/gid
"x" | boolean | True if file1 exists and is executable by
| | the effective uid/gid
"X" | boolean | True if file1 exists and is executable by
| | the real uid/gid
"z" | boolean | True if file1 exists and has a zero length
测试需要两个文件:
"-" | boolean | True if file1 and file2 are identical
"=" | boolean | True if the modification times of file1
| | and file2 are equal
"<" | boolean | True if the modification time of file1
| | is prior to that of file2
">" | boolean | True if the modification time of file1
| | is after that of file2
static VALUE
rb_f_test(int argc, VALUE *argv)
{
int cmd;
if (argc == 0) rb_check_arity(argc, 2, 3);
cmd = NUM2CHR(argv[0]);
if (cmd == 0) {
unknown:
/* unknown command */
if (ISPRINT(cmd)) {
rb_raise(rb_eArgError, "unknown command '%s%c'", cmd == '\'' || cmd == '\\' ? "\\" : "", cmd);
}
else {
rb_raise(rb_eArgError, "unknown command \"\\x%02X\"", cmd);
}
}
if (strchr("bcdefgGkloOprRsSuwWxXz", cmd)) {
CHECK(1);
switch (cmd) {
case 'b':
return rb_file_blockdev_p(0, argv[1]);
case 'c':
return rb_file_chardev_p(0, argv[1]);
case 'd':
return rb_file_directory_p(0, argv[1]);
case 'e':
return rb_file_exist_p(0, argv[1]);
case 'f':
return rb_file_file_p(0, argv[1]);
case 'g':
return rb_file_sgid_p(0, argv[1]);
case 'G':
return rb_file_grpowned_p(0, argv[1]);
case 'k':
return rb_file_sticky_p(0, argv[1]);
case 'l':
return rb_file_symlink_p(0, argv[1]);
case 'o':
return rb_file_owned_p(0, argv[1]);
case 'O':
return rb_file_rowned_p(0, argv[1]);
case 'p':
return rb_file_pipe_p(0, argv[1]);
case 'r':
return rb_file_readable_p(0, argv[1]);
case 'R':
return rb_file_readable_real_p(0, argv[1]);
case 's':
return rb_file_size_p(0, argv[1]);
case 'S':
return rb_file_socket_p(0, argv[1]);
case 'u':
return rb_file_suid_p(0, argv[1]);
case 'w':
return rb_file_writable_p(0, argv[1]);
case 'W':
return rb_file_writable_real_p(0, argv[1]);
case 'x':
return rb_file_executable_p(0, argv[1]);
case 'X':
return rb_file_executable_real_p(0, argv[1]);
case 'z':
return rb_file_zero_p(0, argv[1]);
}
}
if (strchr("MAC", cmd)) {
struct stat st;
VALUE fname = argv[1];
CHECK(1);
if (rb_stat(fname, &st) == -1) {
int e = errno;
FilePathValue(fname);
rb_syserr_fail_path(e, fname);
}
switch (cmd) {
case 'A':
return stat_atime(&st);
case 'M':
return stat_mtime(&st);
case 'C':
return stat_ctime(&st);
}
}
if (cmd == '-') {
CHECK(2);
return rb_file_identical_p(0, argv[1], argv[2]);
}
if (strchr("=<>", cmd)) {
struct stat st1, st2;
struct timespec t1, t2;
CHECK(2);
if (rb_stat(argv[1], &st1) < 0) return Qfalse;
if (rb_stat(argv[2], &st2) < 0) return Qfalse;
t1 = stat_mtimespec(&st1);
t2 = stat_mtimespec(&st2);
switch (cmd) {
case '=':
if (t1.tv_sec == t2.tv_sec && t1.tv_nsec == t2.tv_nsec) return Qtrue;
return Qfalse;
case '>':
if (t1.tv_sec > t2.tv_sec) return Qtrue;
if (t1.tv_sec == t2.tv_sec && t1.tv_nsec > t2.tv_nsec) return Qtrue;
return Qfalse;
case '<':
if (t1.tv_sec < t2.tv_sec) return Qtrue;
if (t1.tv_sec == t2.tv_sec && t1.tv_nsec < t2.tv_nsec) return Qtrue;
return Qfalse;
}
}
goto unknown;
}
trace_var(symbol, cmd ) → nilclick to toggle source
trace_var(symbol) {|val| block } → nil
控制对全局变量的分配跟踪。该参数symbol
标识变量(作为字符串名称或符号标识符)。cmd(它可以是一个字符串或一个Proc
对象),或者在变量被分配时执行块。块或Proc
对象接收变量的新值作为参数。另见Kernel::untrace_var
。
trace_var :$_, proc {|v| puts "$_ is now '#{v}'" }
$_ = "hello"
$_ = ' there'
生成:
$_ is now 'hello'
$_ is now ' there'
VALUE
rb_f_trace_var(int argc, const VALUE *argv)
{
VALUE var, cmd;
struct rb_global_entry *entry;
struct trace_var *trace;
if (rb_scan_args(argc, argv, "11", &var, &cmd) == 1) {
cmd = rb_block_proc();
}
if (NIL_P(cmd)) {
return rb_f_untrace_var(argc, argv);
}
entry = rb_global_entry(rb_to_id(var));
if (OBJ_TAINTED(cmd)) {
rb_raise(rb_eSecurityError, "Insecure: tainted variable trace");
}
trace = ALLOC(struct trace_var);
trace->next = entry->var->trace;
trace->func = rb_trace_eval;
trace->data = cmd;
trace->removed = 0;
entry->var->trace = trace;
return Qnil;
}
trap( signal, command ) → obj
trap( signal ) {| | block } → obj
指定处理信号。第一个参数是信号名称(诸如“SIGALRM”,“SIGUSR1”等的字符串)或信号编号。信号名称中可以省略字符“SIG”。该命令或块指定在信号产生时要运行的代码。如果该命令是字符串“IGNORE”或“SIG_IGN”,则该信号将被忽略。如果该命令是“DEFAULT”或“SIG_DFL”,Ruby的默认处理程序将被调用。如果命令是“EXIT”,那么脚本将被信号终止。如果该命令是“SYSTEM_DEFAULT”,则操作系统的默认处理程序将被调用。否则,将运行给定的命令或块。特殊信号名称“EXIT”或信号编号零将在程序终止之前调用。
Signal.trap(0, proc { puts "Terminating: #{$$}" })
Signal.trap("CLD") { puts "Child died" }
fork && Process.wait
生成:
Terminating: 27461
Child died
Terminating: 27460
static VALUE
sig_trap(int argc, VALUE *argv)
{
int sig;
sighandler_t func;
VALUE cmd;
rb_check_arity(argc, 1, 2);
sig = trap_signm(argv[0]);
if (reserved_signal_p(sig)) {
const char *name = signo2signm(sig);
if (name)
rb_raise(rb_eArgError, "can't trap reserved signal: SIG%s", name);
else
rb_raise(rb_eArgError, "can't trap reserved signal: %d", sig);
}
if (argc == 1) {
cmd = rb_block_proc();
func = sighandler;
}
else {
cmd = argv[1];
func = trap_handler(&cmd, sig);
}
if (OBJ_TAINTED(cmd)) {
rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
}
return trap(sig, func, cmd);
}
untrace_var(symbol [, cmd] ) → array or nil
删除给定全局变量上的指定命令的跟踪并返回nil
。如果没有指定命令,则删除该变量的所有跟踪并返回包含实际删除的命令的数组。
VALUE
rb_f_untrace_var(int argc, const VALUE *argv)
{
VALUE var, cmd;
ID id;
struct rb_global_entry *entry;
struct trace_var *trace;
VALUE data;
rb_scan_args(argc, argv, "11", &var, &cmd);
id = rb_check_id(&var);
if (!id) {
rb_name_error_str(var, "undefined global variable %"PRIsVALUE"", QUOTE(var));
}
if (!rb_id_table_lookup(rb_global_tbl, id, &data)) {
rb_name_error(id, "undefined global variable %"PRIsVALUE"", QUOTE_ID(id));
}
trace = (entry = (struct rb_global_entry *)data)->var->trace;
if (NIL_P(cmd)) {
VALUE ary = rb_ary_new();
while (trace) {
struct trace_var *next = trace->next;
rb_ary_push(ary, (VALUE)trace->data);
trace->removed = 1;
trace = next;
}
if (!entry->var->block_trace) remove_trace(entry->var);
return ary;
}
else {
while (trace) {
if (trace->data == cmd) {
trace->removed = 1;
if (!entry->var->block_trace) remove_trace(entry->var);
return rb_ary_new3(1, cmd);
}
trace = trace->next;
}
}
return Qnil;
}
warn(msg, ...) → nil
除非警告已被禁用(例如使用-W0
标志),否则在STDERR上显示每个给定的消息,后跟一个记录分隔符。
warn("warning 1", "warning 2")
<em>produces:</em>
warning 1
warning 2
static VALUE
rb_warn_m(int argc, VALUE *argv, VALUE exc)
{
if (!NIL_P(ruby_verbose) && argc > 0) {
rb_io_puts(argc, argv, rb_stderr);
}
return Qnil;
}
- 如果文件可以从现有的 Ruby 加载路径加载,那就是。
- 否则,会搜索已安装的宝石以查找匹配的文件。如果它在 gem'y'中找到,则激活该 gem(添加到加载路径中)。
如果该文件已被加载,则返回false 的require
正常功能将被保留。
# File lib/rubygems/core_ext/kernel_require.rb, line 38
def require path
RUBYGEMS_ACTIVATION_MONITOR.enter
path = path.to_path if path.respond_to? :to_path
spec = Gem.find_unresolved_default_spec(path)
if spec
Gem.remove_unresolved_default_spec(spec)
Kernel.send(:gem, spec.name)
end
# If there are no unresolved deps, then we can use just try
# normal require handle loading a gem from the rescue below.
if Gem::Specification.unresolved_deps.empty? then
RUBYGEMS_ACTIVATION_MONITOR.exit
return gem_original_require(path)
end
# If +path+ is for a gem that has already been loaded, don't
# bother trying to find it in an unresolved gem, just go straight
# to normal require.
#--
# TODO request access to the C implementation of this to speed up RubyGems
spec = Gem::Specification.find_active_stub_by_path path
begin
RUBYGEMS_ACTIVATION_MONITOR.exit
return gem_original_require(path)
end if spec
# Attempt to find +path+ in any unresolved gems...
found_specs = Gem::Specification.find_in_unresolved path
# If there are no directly unresolved gems, then try and find +path+
# in any gems that are available via the currently unresolved gems.
# For example, given:
#
# a => b => c => d
#
# If a and b are currently active with c being unresolved and d.rb is
# requested, then find_in_unresolved_tree will find d.rb in d because
# it's a dependency of c.
#
if found_specs.empty? then
found_specs = Gem::Specification.find_in_unresolved_tree path
found_specs.each do |found_spec|
found_spec.activate
end
# We found +path+ directly in an unresolved gem. Now we figure out, of
# the possible found specs, which one we should activate.
else
# Check that all the found specs are just different
# versions of the same gem
names = found_specs.map(&:name).uniq
if names.size > 1 then
RUBYGEMS_ACTIVATION_MONITOR.exit
raise Gem::LoadError, "#{path} found in multiple gems: #{names.join ', '}"
end
# Ok, now find a gem that has no conflicts, starting
# at the highest version.
valid = found_specs.reject { |s| s.has_conflicts? }.first
unless valid then
le = Gem::LoadError.new "unable to find a version of '#{names.first}' to activate"
le.name = names.first
RUBYGEMS_ACTIVATION_MONITOR.exit
raise le
end
valid.activate
end
RUBYGEMS_ACTIVATION_MONITOR.exit
return gem_original_require(path)
rescue LoadError => load_error
RUBYGEMS_ACTIVATION_MONITOR.enter
begin
if load_error.message.start_with?("Could not find") or
(load_error.message.end_with?(path) and Gem.try_activate(path)) then
require_again = true
end
ensure
RUBYGEMS_ACTIVATION_MONITOR.exit
end
return gem_original_require(path) if require_again
raise load_error
end
另外别名为:gem_original_require
scanf(格式,&b)显示来源
扫描 STDIN 进行数据匹配format
。有关详细信息,请参阅 IO#scanf。
有关创建格式字符串的详细信息,请参阅 Scanf。
你将需要'scanf'来使用 #scanf。
# File lib/scanf.rb, line 772
def scanf(format, &b) #:doc:
STDIN.scanf(format ,&b)
end
y(*objects)显示源
旨在与 IRB 一起使用的 Psych.dump_stream 的别名。
# File ext/psych/lib/psych/y.rb, line 4
def y *objects
puts Psych.dump_stream(*objects)
end
本文档系腾讯云开发者社区成员共同维护,如有问题请联系 cloudcommunity@tencent.com