参考手册:标准库——内部模块

参考手册:标准库——内部模块

为那些可进行比较运算的类准备的Mix-in. 在那些包含该模块的类中, 必须已定义了基本的比较操作符<=>. 这样就可以利用该定义来派生出其他的操作符.
方法:

self == other

  若self与other相等, 则返回真.

  ruby 1.8 特性: 若<=> 返回nil, 则返回nil.
self > other

  若self大于other, 则返回真.

  ruby 1.8 特性:若<=> 返回 nil,则引发异常ArgumentError.
self >= other

  若self大于等于other, 则返回真.

  ruby 1.8 特性: 若<=> 返回 nil,则引发异常ArgumentError.
self < other

  若self小于other, 则返回真.

  ruby 1.8 特性: 若<=> 返回 nil,则引发异常ArgumentError.
self <= other

  若self小于等于other, 则返回真.

  ruby 1.8 特性: 若<=> 返回 nil,则引发异常ArgumentError.
between?(min, max)

  若self处于从min到max的范围之中时,返回真.

  ruby 1.8 特性: 若self <=> min或self <=> max返回nil,则引发异常ArgumentError.
为那些进行循环操作的类准备的Mix-in. 本模块中定义的方法都用到了each,因此在那些包含本模块的类中,必需预先定义了each才行.
方法:

all?
all? {|item| ... }

  ruby 1.7 特性:

  当所有元素都为真时,返回true. 若某元素为假时, 立即返回false.

  ruby 1.8 特性: 若带块调用时, 会依次为各个元素来执行块的内容, 若所有的结果都为真,则返回true. 一旦块返回假时, 立即返回false.

  p [1,2,3].all? {|v| v > 0} # => true
  p [1,2,3].all? {|v| v > 1} # => false

any?
any? {|item| ... }

  ruby 1.7 特性:

  当所有元素都为假时,返回false. 一旦某元素为真时, 立即返回true.

  ruby 1.8 特性: 若带块调用时, 会依次为各个元素来执行块的内容, 若所有的结果都为假,则返回false. 一旦块返回真时, 立即返回true.

  p [1,2,3].any? {|v| v > 3} # => false
  p [1,2,3].any? {|v| v > 1} # => true

collect {|item| ... }
map {|item| ... }

  依此为各元素执行块的内容,并将结果存入数组,最后返回该数组.

  省略块时,会执行

  obj.collect {|item| item}

  这等同于Enumerable#to_a.
each_with_index {|item,index| ... }

  使用元素及其索引进行循环操作的迭代器.

  返回self.
find([ifnone]) {|item| ... }
detect([ifnone]) {|item| ... }

  在使用元素进行块的计算时, 返回计算值首次为真的那个元素. 若块的计算值始终都不为真时, 则计算ifnone部分(若有的话),并返回nil. (ruby 1.7 特性: 返回ifnone的计算值.)

  ifnone可以是字符串或带call方法的对象(例如Proc).

  [1,2,3].find("raise") {|v| v > 4}
  # => -:1: unhandled exception

  ruby 1.7 特性: ifnone不能是字符串了.
find_all {|item| ... }
select {|item| ... }

  在使用元素进行块的计算时,若计算值为真则把该元素存入数组,最后返回该数组. 若块的计算值始终都不为真时,则返回空数组.
grep(pattern)
grep(pattern) {|item| ... }

  若pattern === item,则把该元素存入数组,最后返回该数组. 若带块调用时, 则会依次为所有满足上述条件的元素来执行块的内容, 并把计算结果存入数组,最后返回该数组. 若没有符合条件的元素时, 返回空数组.
inject([init]) {|result, item| ... } ((<ruby 1.7 特性>))

  开始时,把初始值init和self的首元素当做块参数来计算块的内容. 从第2次循环开始, 将把上次的块的计算结果和self的下个元素当做块参数来计算块. 这样一直循环到最后的元素, 返回最后的块的计算结果.

  若没有元素,则返回init.

  若省略了初始值init的话, 开始时会把第1和第2个元素传递给块. 此时, 若只有1个元素时,将直接返回首元素,而不会执行块. 若没有元素,则返回nil.

  例

   求和的计算

   p [1,2,3,4,5].inject(0) {|result, item| result + item }
    => 15

   这等同于

   result = 0
   [1,2,3,4,5].each {|v| result += v }
   p result
   => 15

member?(val)
include?(val)

  若val==某元素时,返回真.
max

  返回最大的元素. 该方法假定所有元素都是可以使用<=>方法来进行比较的.
max {|a, b| ... }

  以块的计算结果来判断各个元素的大小, 并返回最大的元素.

  通常要求该块返回下列各整数值: 当a>b时返回正整数,a==b时返回0,而a<b时返回负整数. 若该块返回了一个非整数值时, 会引发TypeError异常.
max_by {|item| ... } ((<ruby 1.9 特性>))

  以<=>来比较块的计算值, 并返回最大的元素.

  max与max_by间的差别就如同sort与sort_by间的不同一样. 详情请参考sort_by.
min

  返回最小的元素. 该方法假定所有元素都是可以使用<=>方法来进行比较的.
min {|a, b| ... }

  以块的计算结果来判断各个元素的大小, 并返回最小的元素.

  通常要求该块返回下列各整数值: 当a>b时返回正整数,a==b时返回0,而a<b时返回负整数. 若该块返回了一个非整数值时, 会引发TypeError异常.
min_by {|item| ... } ((<ruby 1.9 特性>))

  以<=>来比较块的计算值, 并返回最小的元素.

  min与min_by间的差别就如同sort与sort_by间的不同一样. 详情请参考sort_by.
partition {|item| ... } ((<ruby 1.7 特性>))

  若对某元素执行块的结果为真, 则把该元素归入第一个数组;若为假则将其归入第二个数组,最后生成并返回一个包含这两个数组的新数组.

  [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0].partition { |i| i % 3 == 0 }
  #=> [[9, 6, 3, 0], [10, 8, 7, 5, 4, 2, 1]]

reject {|item| ... }

  依此为各元素计算块的内容, 若计算值为假则将该元素存入数组,最后返回该数组.
sort
sort {|a, b| ... }

  对所有元素进行升序排列后返回这个新的数组.

  若不带块时, 将以<=>方法的比较结果为基础进行排序.

  如果想借用<=>之外的方法进行排序时,可以指定一个块. 此时将以块的计算结果为基础进行排序. 通常要求该块返回下列各值: 当a>b时返回正整数,a==b时返回0,而a<b时返回负整数. 若该块返回了一个非整数值时, 会引发TypeError异常.

  Enumerable#sort 所进行的是不稳定的排序(unstable sort)。

  注: 排序后,若相等的元素的位置并未改变的话,这种排序就是"稳定的排序(stable sort)".
sort_by {|item| ... } ((<ruby 1.7 特性>))

  以<=>方法来比较块的计算值, 并对self进行升序排列,最后生成并返回新生成的数组. 这基本上等同于

  class Array
  def sort_by
   self.collect {|i| [yield(i), i] }.
    sort {|a,b| a[0] <=> b[0] }.
    collect! {|i| i[1]}
  end
  end

  在下例中并未使用sort_by, 每次进行比较时都会执行downcase. 所以,若downcase的运行速度较慢时, 将会对sort的速度造成致命的影响.

  p ["BAR", "FOO", "bar", "foo"].sort {|a,b| a.downcase <=> b.downcase }

  另一方面,下例中使用了sort_by,此时downcase的运行次数取决于元素个数.

  p ["BAR", "FOO", "bar", "foo"].sort_by {|v| v.downcase }

  下例中检验了它的执行次数,供您参考.

  class Integer
  def count
   $n += 1
   self
  end
  end

  ary = []
  1.upto(1000) {|v| ary << rand(v) }

  $n = 0
  ary.sort {|a,b| a.count <=> b.count }
  p $n    # => 18200

  $n = 0
  ary.sort_by {|v| v.count }
  p $n    # => 1000

  Enumerable#sort_by 是不稳定的排序(unstable sort)。

  注: 排序后,若相等的元素的位置并未改变的话,这种排序就是"稳定的排序(stable sort)".

  您可以像下例这样来实现稳定排序.

  i = 0
  ary.sort_by {|v| [v, i += 1] }

to_a
entries

  返回包含所有元素的数组.
zip([ary1[, ary2[, ...]]])
zip([ary1[, ary2[, ...]]]) {|v1, v2, ...| ...}

  ruby 1.7 特性:

  生成并返回一个由self和参数数组中的元素构成的数组的数组. 新数组的元素个数取决于self中的元素数.

  p [1,2,3].zip([4,5,6], [7,8,9])
  => [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

  p [1,2].zip([:a,:b,:c], [:A,:B,:C,:D])
  => [[1, :a, :A], [2, :b, :B]]

  p (1..5).zip([:a,:b,:c], [:A,:B,:C,:D])
  => [[1, :a, :A], [2, :b, :B], [3, :c, :C], [4, nil, :D], [5, nil, nil]]

  带块调用时, 将把各数组作为参数传递给块,然后计算该块. 通常zip会返回nil.

  p [1,2,3].zip([4,5,6], [7,8,9]) {|ary|
  p ary
  }
  => [1, 4, 7]
   [2, 5, 8]
   [3, 6, 9]
   nil
该模块中囊括了与系统调用的错误相对应的异常.
内部类:定义了下列异常类. 各异常的具体含义要看所用系统而定. 请参考 Errno:EXXX 来了解这些类的细节.
若发生了Ruby所不了解的(即,未在下面列出的)系统错误时, 将生成名为Errno::Exxx (xxx是表示错误编号的3位数)的异常类.
ERROR该异常类只用于BeOS.
EPERMENOENTESRCHEINTREIOENXIOE2BIGENOEXECEBADFECHILDEAGAINENOMEMEACCESEFAULTENOTBLKEBUSYEEXISTEXDEVENODEVENOTDIREISDIREINVALENFILEEMFILEENOTTYETXTBSYEFBIGENOSPCESPIPEEROFSEMLINKEPIPEEDOMERANGEEDEADLKENAMETOOLONGENOLCKENOSYSENOTEMPTYELOOPEWOULDBLOCKENOMSGEIDRMECHRNGEL2NSYNCEL3HLTEL3RSTELNRNGEUNATCHENOCSIEL2HLTEBADEEBADREXFULLENOANOEBADRQCEBADSLTEDEADLOCKEBFONTENOSTRENODATAETIMEENOSRENONETENOPKGEREMOTEENOLINKEADVESRMNTECOMMEPROTOEMULTIHOPEDOTDOTEBADMSGEOVERFLOWENOTUNIQEBADFDEREMCHGELIBACCELIBBADELIBSCNELIBMAXELIBEXECEILSEQERESTARTESTRPIPEEUSERSENOTSOCKEDESTADDRREQEMSGSIZEEPROTOTYPEENOPROTOOPTEPROTONOSUPPORTESOCKTNOSUPPORTEOPNOTSUPPEPFNOSUPPORTEAFNOSUPPORTEADDRINUSEEADDRNOTAVAILENETDOWNENETUNREACHENETRESETECONNABORTEDECONNRESETENOBUFSEISCONNENOTCONNESHUTDOWNETOOMANYREFSETIMEDOUTECONNREFUSEDEHOSTDOWNEHOSTUNREACHEALREADYEINPROGRESSESTALEEUCLEANENOTNAMENAVAILEISNAMEREMOTEIOEDQUOT
该模块囊括了与File类有关的常数.
File类包含该模块,因此您可以像使用File类的常数那样来使用下列常数.
常数下列常数用于File#flock.
LOCK_SH共享锁. 可同时被多个进程所共享的锁.
LOCK_EX互斥锁. 只能单独被某进程所使用的锁.
LOCK_UN解锁.
LOCK_NB锁定时不会进入阻塞状态. 使用 or 后,可与其他常数并用.
下列常数用于File.open.
RDONLYWRONLYRDWRAPPENDCREATEXCLNONBLOCKTRUNCNOCTTYBINARYSYNC下列常数用于File.fnmatch和Dir.glob中. ruby 1.7 特性
FNM_NOESCAPEFNM_PATHNAMEFNM_PERIODFNM_CASEFOLDFNM_DOTMATCH
FileTest模块中包含了文件的测试函数.
模块函数:FileTest.blockdev?(filename)若filename是块专用文件,就返回真。
FileTest.chardev?(filename)若filename是字符专用文件,就返回真。
FileTest.executable?(filename)若能用有效用户/组ID来执行filename的话,就返回真。
FileTest.executable_real?(filename)若能用实用户/组ID来执行filename的话,就返回真。
FileTest.exist?(filename)若filename确实存在, 就返回真。
FileTest.grpowned?(filename)若filename的组ID与执行组ID相等, 就返回真.
FileTest.directory?(filename)若filename是目录名, 就返回真。
FileTest.file?(filename)若filaname是普通文件,就返回真。
FileTest.pipe?(filename)若filename是带名的管道(FIFO),就返回真。
FileTest.socket?(filename)若filename是socket,就返回真。
FileTest.owned?(filename)若filename属于自己,则返回真。
FileTest.readable?(filename)若filename可读,则返回真。
FileTest.readable_real?(filename)若filename可被实用户/实组所读取时,返回真。
FileTest.setuid?(filename)若filename被setuid(2)的话,就返回真。
FileTest.setgid?(filename)若filename被setgid(2)的话,就返回真。
FileTest.size(filename)返回filename的大小. 若filename不存在,则引发Errno::EXXX(可能是Errno::ENOENT)异常。
请参考FileTest.size?, FileTest.zero?。
FileTest.size?(filename)返回filename的大小. 若filename不存在或filename的大小为0时, 返回nil。
请参考FileTest.size, FileTest.zero?。
FileTest.sticky?(filename)若filename的sticky位(请参考chmod(2))为真,则返回真。
FileTest.symlink?(filename)若filename是符号连接,则返回真。
FileTest.writable?(filename)若filename可写,则返回真。
FileTest.writable_real?(filename)若filename可被实用户/实组所写入时,返回真。
FileTest.zero?(filename)若filename确实存在,且其大小为0时,就返回真。若filename不存在,则返回false。
请参考FileTest.size, FileTest.size?。
GC是用来控制Ruby解释器的"垃圾回收(Garbage Collection)"的模块.
模块方法:GC.disable禁止使用垃圾回收.
返回此前的禁用状态(若此前已被禁用,则返回true;若此前GC仍在工作,则返回false).
GC.enable允许使用垃圾回收.
返回此前的禁用状态(若此前已被禁用,则返回true;若此前GC仍在工作,则返回false).
GC.start启动垃圾回收.
返回nil.
方法:garbage_collect启动垃圾回收. 它相当于
GC.start
返回nil.
该模块中定义了可供所有类使用的方法. Object类中包含了该模块. 内部函数中提到的那些方法,实际上是在该模块中定义的.
Object类中的方法实际上是在该模块中定义的. 这是为了与在顶层中的方法的再定义取得对应关系.
您可以使用该模块把Ruby对象写入文件(或字符串)保存起来,或者重新读取并生成该对象. 绝大部分类的实例都是可以保存的, 但有的类确实不行(后述).
下文中提到的"marshal data"是指Marshal.dump输出的字符串.
模块函数:Marshal.dump(obj[,port][,limit])把obj递归地写入文件. 若对那些不能被写入文件的对象使用该函数时, 会引发TypeError异常. 下列对象就不能被写入文件.
  • 无名的Class/Module对象. (此时,将引发ArgumentError异常. 请参考Module.new来了解无名类的情况.)
  • 其状态受到系统保护的那些对象. 具体说来就是以下实例. 例如Dir, File::Stat, IO及其子类File, Socket等.
  • MatchData, Data, Method, UnboundMethod,Proc, Thread, ThreadGroup, Continuation的实例.
  • 定义了特殊方法的对象
另外,间接指向上述对象的那些对象也是不可保存的. 例如, Hash内部包含求默认值的块, 实际上,它是间接地指向Proc的.
p Marshal.dump(Hash.new {})
=> -:1:in `dump': cannot dump hash with default proc (TypeError)
可以向port指定一个IO(或其子类)的实例. 此时将返回port. 缺省时, dump会返回保存着对象的字符串.
若使用了limit时, 将只会保存limit层以内的关联对象(默认值为100层). 若将limit指定为负值时, 将不会进行层数检查.
您可以自由地定义marshal的运作细节, 详情请参考用户定义的Marshal.
Marshal.load(port[,proc])Marshal.restore(port[,proc])从port读入marshal data后生成一个与原对象状态相同的对象. port可以是字符串或IO(或其子类)的实例.
若给出了过程对象proc时, 将以读入的对象作参数来调用该过程对象.
str = Marshal.dump(["a", 1, 10 ** 10, 1.0, :foo])
p Marshal.load(str, proc {|obj| p obj})

=> "a"
 1
 10000000000
 1.0
 :foo
 ["a", 1, 10000000000, 1.0, :foo]
 ["a", 1, 10000000000, 1.0, :foo]
常数:MAJOR_VERSION  ((<ruby 1.7 特性>))MINOR_VERSION  ((<ruby 1.7 特性>))Marshal.dump输出的数据格式的版本号.
在Marshal.load中, 若major version不同,或者读入了高版本的marshal data时, 会引发TypeError异常.
minor version版本较低的数据是可读的. 但若$VERBOSE = true时, 将出现警告消息.
可以使用下面的方法来获得数据的版本号.
obj = Object.new
major, minor = Marshal.dump(obj).unpack("cc")
p [major, minor]
用户定义的MarshalObject#_dump(limit)Class#_load(str)使用Marshal.dump保存对象时, 若该对象中已经定义了`_dump'方法的话, 就直接使用该方法的返回值. `_dump'方法接受limit对递归操作的限制, 将对象变为字符串并返回结果.
若某类的实例中包含`_dump'方法的话, 则该类中必需包含一个名为`_load'的类方法, 它负责读回数据. `_load'在收到一个保存着对象的字符串之后, 必须将它还原为对象.
class Foo
 def initialize(obj)
  p "initialize() called"
  @foo = obj
 end
 def _dump(limit)
  Marshal.dump(@foo, limit)
 end
 def self._load(obj)
  Foo.new(Marshal.load(obj))
 end
end

p Marshal.load(Marshal.dump(Foo.new(['foo', 'bar'])))

=> "initialize() called"
 "initialize() called"
 #<Foo:0x4019eb88 @foo=["foo", "bar"]>
通常情况下, 实例变量的信息都被保存在marshal data中, 所以不必像上例那样去定义 _dump(但是,若定义了_dump的话, 实例变量的信息就不会被保存下来了). 若您想进行更加灵活的控制,或者扩展库中定义的类的实例需要保存除实例变量之外的更多信息时, 可以使用_dump/_load. (例如Time类就定义了_dump/_load)
Object#marshal_dump   ((<ruby 1.8 特性>))Object#marshal_load   ((<ruby 1.8 特性>))在使用Marshal.dump保存对象时, 若该对象中已定义了`marshal_dump'方法的话, 就直接使用该方法的返回值. marshal_dump被设计成一个可以返回任意对象的方法.
因此,在load这样的对象时, 就必需事先定义过一个名为`marshal_load'的方法. marshal_load接收marshal_dump返回值的拷贝. 此时marshal_load的self处于新生(刚被allocate的)状态. 另外, marshal_load的返回值将被忽略.
若该对象中同时包含 _dump 和 marshal_dump 方法时, 将使用 marshal_dump 方法.
class Foo
 def initialize
  p "initialize() called"
  @foo = ['foo', 'bar']
 end
 def marshal_dump
  @foo
 end
 def marshal_load(obj)
  @foo = obj
 end
end

p Marshal.load(Marshal.dump(Foo.new))

"initialize() called"
#<Foo:0x4019ed2c @foo=["foo", "bar"]>
通常情况下, 实例变量的信息会被保存在marshal data中, 所以不必像上例那样去定义 marshal_dump(但是,若定义了marshal_dump的话,实例变量的信息就不会被保存下来了,所以必须使用marshal_dump/marshal_load来进行处理). 若您想进行更加灵活的控制,或者扩展库中定义的类的实例需要保存除实例变量之外的更多信息时, 可以使用marshal_dump/marshal_load.
而且, 若某对象中已经定义了marshal_dump/marshal_load的话, 即时其内部包含特殊方法, 也可以进行保存. (这并不是说特殊方法会被自动保存下来, 而是说您可以通过marshal_dump/marshal_load来进行相应的处理)
支持浮点运算的类. 在Math模块中, 定义了两套内容相同的方法和特殊方法, 因此,既可以使用模块的特殊方法, 又可以将模块包含到类中之后,使用它的普通方法.
例:
pi = Math.atan2(1, 1)*4;
include Math
pi2 = atan2(1, 1)*4
模块函数:Math.acos(x)Math.asin(x)Math.atan(x)以弧度返回x的反三角函数值.
返回值的范围分别是[0, +π]  、[-π/2, +π/2]、  (-π/2, +π/2).
在acos(x), asin(x)中,x的取值范围必为 -1.0 <= x <= 1 .(通常返回NaN)
ruby 1.7 特性: acos(), asin()遇到超出范围的参数时,会引发Errno::EDOM异常.
Math.atan2(y, x)返回  [-π , π]     之间的  y/x的反正切值.
Math.acosh(x) ((<ruby 1.7 特性>))Math.asinh(x) ((<ruby 1.7 特性>))Math.atanh(x) ((<ruby 1.7 特性>))返回x的反双曲线函数值.
asinh(x) = log(x + sqrt(x * x + 1))
acosh(x) = log(x + sqrt(x * x - 1)) [x >= 1]
atanh(x) = log((1+x)/(1-x)) / 2  [-1 < x < 1]
在acosh(x)中,x的取值范围是x >= 1 . (通常会引发Errno::EDOM异常)
在atanh(x)中,x的取值范围是 -1.0 < x < 1 .(通常会引发Errno::EDOM异常)
Math.cos(x)Math.sin(x)Math.tan(x)返回[-1, 1]之间的以弧度表示的x的三角函数值.
Math.cosh(x) ((<ruby 1.7 特性>))Math.sinh(x) ((<ruby 1.7 特性>))Math.tanh(x) ((<ruby 1.7 特性>))返回x的双曲线函数的值.
cosh(x) = (exp(x) + exp(-x)) / 2
sinh(x) = (exp(x) - exp(-x)) / 2
tanh(x) = sinh(x) / cosh(x)
Math.erf(x) ((<ruby 1.8 特性>))Math.erfc(x) ((<ruby 1.8 特性>))返回 x 的误差函数(erf)、补余误差函数(erfc)的值.
Math.exp(x)返回x 的指数函数的值.
Math.frexp(x)返回实数x 的指数部分和假数部分.
Math.hypot(x, y) ((<ruby 1.7 特性>))返回sqrt(x*x + y*y).
Math.ldexp(x,exp)先以2为底数进行exp的指数运算, 然后乘以实数x,返回计算结果.
Math.log(x)返回x的自然对数.
x必为正数(通常情况下, 若为负值则返回NaN , 若为0则返回-Infinity)
ruby 1.7 特性: 遇到超出范围的参数时, 若为负数则引发Errno::EDOM异常, 若为0则引发Errno::ERANGE异常.
Math.log10(x)返回x的常用对数.
x必为正数(通常情况下, 若为负值则返回NaN , 若为0则返回-Infinity)
ruby 1.7 特性: 遇到超出范围的参数时, 若为负数则引发Errno::EDOM异常, 若为0则引发Errno::ERANGE异常.
Math.sqrt(x)返回x的平方根. 若x为负值, 则引发ArgumentError异常.
ruby 1.7 特性: 通常情况下, 若x为负值,则引发Errno::EDOM异常.
常数:E自然对数的底数
p Math::E
# => 2.718281828
PI圆周率
p Math::PI
# => 3.141592654
用来操作所有对象的模块.
模块函数:ObjectSpace._id2ref(id)利用对象ID(Object#id)获取对象. 若没有相应的对象则引发RangeError异常.
ObjectSpace.define_finalizer(obj, proc)ObjectSpace.define_finalizer(obj) {|id| ...}注册销毁对象时所要执行的finalizer proc. 若多次针对同一对象调用该函数时, 会进行追加注册而并非替换操作.
通常把Proc对象当做finalizer传给proc. 若使用块的话, 该块就成为proc(但是,正如后文中提到的那样,使用块来注册finalizer是比较困难的)。
obj的ID(Object#id)会被当做参数传递给finalizer proc。
不要像下面这样来使用define_finalizer。
class Foo
 def initialize
  ObjectSpace.define_finalizer(self) {
  puts "foo"
  }
 end
end
Foo.new
GC.start
此时, proc的self仍在使用obj, 所以该对象不能被GC回收。
[ruby-src:lib/tempfile.rb]堪称演示finalizer用法的优秀范本. 它在类的上下文(context)中生成Proc,巧妙地避开了上面提到的问题.
class Bar
 def Bar.callback
  proc {
  puts "bar"
  }
 end
 def initialize
  ObjectSpace.define_finalizer(self, Bar.callback)
 end
end
Bar.new
GC.start
在调用proc的过程中,即使发生了大规模退出(non-local exit)的话(exit或异常)也会被忽略. 这主要是为了防止脚本的主处理过程因GC而被非同步中断所采取的措施. 为了以防万一, 最好事先使用-d选项来测试一下是否会发生异常.
class Baz
 def initialize
  ObjectSpace.define_finalizer self, eval %q{
  proc {
   raise "baz" rescue puts $!
   raise "baz2"
   puts "baz3"
  }
  }, TOPLEVEL_BINDING
 end
end
Baz.new
GC.start

# => baz
ObjectSpace.each_object([class_or_module]) {|object| ...}若某对象的kind_of?与class_or_module一致时,就对其进行迭代操作. 若省略参数,则对所有对象进行迭代操作.
若将class_or_module指定为Fixnum或Symbol的话, 则不会进行任何操作.
返回迭代操作的次数.
ObjectSpace.garbage_collect回收那些已作废的对象. 与GC#start相同.
返回nil.
ObjectSpace.undefine_finalizer(obj)取消obj的所有的finalizer.
返回obj.
以下这些是finalizer的以前的接口. 若使用它们的话,会收到警告信息.
ObjectSpace.add_finalizer(proc)  ((<obsolete>))将proc设为finalizer.
若销毁call_finalizer所指定的对象时, 将以该对象的ID(c.f Object#id)为参数来调用finalizer.
返回proc.
该方法已经停用(obsolete). 请使用ObjectSpace.define_finalizer.
ObjectSpace.call_finalizer(obj)  ((<obsolete>))将obj设为与finalizer相对应的对象.
返回obj.
该方法已经停用(obsolete).
ObjectSpace.finalizers  ((<obsolete>))以数组的形式返回当前已注册的finalizer.
该方法已经停用(obsolete).
ObjectSpace.remove_finalizer(proc) ((<obsolete>))从finalizer中删除指定的proc.
返回proc.
该方法已经停用(obsolete). 请使用ObjectSpace.undefine_finalizer.