Ruby 2.4

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_hasharg 转换为一个Hash。当argnil[]时,返回空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,当基极被省略或等于零,基数指示符(00b,和0x)被兑现。无论如何,字符串应严格符合数字表示。这种行为不同于String#to_ito_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会在当前上下文中执行块返回trueiterator?表格被轻度弃用。

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_idTAG2。找到时,块停止执行并返回 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就直接调用该命令

  • 一个事件名称

  • 一个文件名

  • 一个行号

  • 一个对象 ID

  • 一个绑定

  • 一个classproc的名称

  • 如果文件可以从现有的 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