directory search
Ruby用户指南 3、开始 4、简单的例子 5、字符串 6、正则表达式 7、数组 8、回到那些简单的例子 9、流程控制 10、迭代器 11、面向对象思维 12、方法 13、类 14、继承 15、重载方法 16、访问控制 17、单态方法 18、模块 19、过程对象 20、变量 21、全局变量 22、实变量 23、局部变量 24、类常量 25、异常处理:rescue 26、异常处理:ensure 27、存取器 28、对象的初始化 29、杂项 RGSS入门教程 1、什么是RGSS 2、开始:最简单的脚本 3、数据类型:数字 4、数据类型:常量与变量 5、数据类型:字符串 6、控制语句:条件分歧语句 7、控制语句:循环 8、函数 9、对象与类 10、显示图片 11、数组 12、哈希表(关联数组) 13、类 14、数据库 15、游戏对象 16、精灵的管理 17、窗口的管理 18、活动指令 19、场景类 Programming Ruby的翻译 Programming Ruby: The Pragmatic Programmer's Guide 前言 Roadmap Ruby.new 类,对象和变量 容器Containers,块Blocks和迭代Iterators 标准类型 深入方法 表达式Expressions 异常,捕捉和抛出(已经开始,by jellen) 模块 基本输入输出 线程和进程 当遭遇挫折 Ruby和它的世界 Ruby和Web开发 Ruby Tk Ruby 和微软的 Windows 扩展Ruby Ruby语言 (by jellen) 类和对象 (by jellen) Ruby安全 反射Reflection 内建类和方法 标准库 OO设计 网络和Web库 Windows支持 内嵌文档 交互式Ruby Shell 支持 Ruby参考手册 Ruby首页 卷首语 Ruby的启动 环境变量 对象 执行 结束时的相关处理 线程 安全模型 正则表达式 字句构造 程序 变量和常数 字面值 操作符表达式 控制结构 方法调用 类/方法的定义 内部函数 内部变量 内部常数 内部类/模块/异常类 附加库 Ruby变更记录 ruby 1.6 特性 ruby 1.7 特性 Ruby术语集 Ruby的运行平台 pack模板字符串 sprintf格式 Marshal格式 Ruby FAQ Ruby的陷阱
characters

ruby 1.6 特性

ruby version 1.6是稳定版。在该版本中,主要修改了一些bug。

stable-snapshot是稳定版的源代码,且每日更新。

1.6.8 (2002-12-24) -> stable-snapshot

2003-01-22: errno

在EAGAIN与EWOULDBLOCK同值的系统中,EWOULDBLOCK消失不见了。现在,这种系统中的EWOULDBLOCK被定义为EAGAIN。(这点与1.6.7不同)

p Errno::EAGAIN
p Errno::EWOULDBLOCK

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   Errno::EAGAIN
   Errno::EWOULDBLOCK

=> ruby 1.6.8 (2002-12-24) [i586-linux]
   Errno::EAGAIN
   -:2: uninitialized constant EWOULDBLOCK at Errno (NameError)

=> ruby 1.6.8 (2003-02-13) [i586-linux]
   Errno::EAGAIN
   Errno::EAGAIN

1.6.7 (2002-03-01) -> 1.6.8 (2002-12-24)

2002-10-02: Thread (cygwin)

在Cygwin中,有时无法切换Thread。 [ruby-list:36058], [ruby-list:24637]

2002-10-01: Socket (win)

好像解决了一个Windows中的socket问题。(从原来的邮件中无法得到具体的问题描述,但好像是:虽然可以用select来进行读入,但返回的是空数组) [ruby-talk:40015], [ruby-win32:366]

2002-09-12: Thread.status (?)

有时用trap捕获信号时却并没有保存线程的状态,导致被信号中断的线程状态混乱[ruby-talk:40337], [ruby-core:00019]

2002-09-11: Queue#pop

Queue#pop中存在竞争问题[ruby-dev:17223]

2002-09-11: SizedQueue.new

修改了可接受0以下的参数的bug。

2002-09-05: 展开式

在stable snapshot中,曾经有一段时间,需要对展开式中引号使用反斜线转义。该变更解决了这个问题。

p "#{ "" }"

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   ""

=> -:1: warning: bad substitution in string
   ruby 1.6.7 (2002-09-12) [i586-linux]
   "#{  }"

=> ruby 1.6.7 (2002-09-25) [i586-linux]
   ""

这并不是1.7之后的backport。在处理注释等对象时,与1.7有所不同。(请参考ruby 1.7 特性的2002-06-24)

p "#{ "" # comment }"
=> ruby 1.6.8 (2002-10-04) [i586-linux]
   ""
=> -:1: parse error
   ruby 1.7.3 (2002-10-04) [i586-linux]
SizedQueue#deq, #shift
SizedQueue#enq

添加(push, pop的别名)。以前尚未定义它们时,调用enq等就会执行超类Queue的enq。

2002-09-11: Tempfile#size

添加[ruby-dev:17221]

2002-09-09

在mswin32版和mingw32版的ruby中,从1.6.6版起就有一个bug:ruby的子进程无法接收环境变量。[ruby-dev:18236]

2002-09-03

在使用Bison编译的Ruby中,多次加载库的速度有所提高。(若不使用Bison的话,每次加载时,好像都会显式地执行GC,所以运行速度会下降) [ruby-dev:18145]

2002-08-20 File.expand_path

Cygwin 1.3.x [ruby-bugs-ja:PR#299]

p File.expand_path('file', 'c:/')

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   /tmp/c:/file
=> ruby 1.6.7 (2002-08-21) [i586-linux]
   c:/file
2002-08-19 Thread (win)

以前,同时使用Ruby线程和Win32的结构化异常(包括来自Win32 API的callback)的话就会引起故障。现在该bug已被修复。[ruby-win32:273]

2002-08-12 Hash#==

以前,只要两个Hash对象的默认值(default)==的话,它们也就被看作相等。

p Hash.new("foo") == Hash.new("bar")

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   true
=> ruby 1.6.7 (2002-08-21) [i586-linux]
   false
2002-07-11 String#slice!

以前,若指定了范围之外的字符串的话,有时会返回异常。现在统一返回nil。(也就是返回与String#[]或String#slice一样的结果)

p "foo".slice!("bar")   # <- 以前此处返回 nil
p "foo".slice!(5,10)

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   nil
   -:2:in `slice!': index 5 out of string (IndexError)
        from -:2
=> ruby 1.6.7 (2002-08-01) [i586-linux]
   nil
   nil
2002-07-05 String#split

现在可以给第一个参数指定nil了。[ruby-talk:43513] 此时把$;当作分割字符串。以前,只有省略参数时才能使用$;。

$; = ":"
p "a:b:c".split(nil)
=> -:2:in `split': bad separator (ArgumentError)
        from -:2
   ruby 1.6.7 (2002-03-01) [i586-linux]

=> ruby 1.6.7 (2002-07-30) [i586-linux]
   ["a", "b", "c"]
2002-06-15 Dir.glob

以前,Dir.glob不会匹配已断链的符号连接。

File.symlink("foo", "bar")
p Dir.glob("bar")
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   []
=> ruby 1.6.7 (2002-08-01) [i586-linux]
   ["bar"]
2002-06-13 Hash[]

以前,无法用Hash[]来dup & freeze键字符串。

a = "key"
h = Hash[a,"val"]
h.keys[0].upcase!
p a
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   "KEY"
=> -:3:in `upcase!': can't modify frozen string (TypeError)
        from -:3
   ruby 1.6.7 (2002-08-01) [i586-linux]
2002-06-10 Fixnum#>>, <<

有时对负数进行右移位时,就会变成0。 [ruby-bugs-ja:PR#247]

以负数为参数的左移位(即右移位)中也会出现这种问题。[ruby-bugs-ja:PR#248]

p(-1 >> 31)
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   0
=> ruby 1.6.7 (2002-08-01) [i586-linux]
   -1

p(-1 << -1)
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   -2147483649
=> ruby 1.6.7 (2002-08-01) [i586-linux]
   -1
2002-06-05
Math.acosh
Math.asinh
Math.atanh

添加。

2002-06-03
String#[]=

若receiver中不包含指定的索引字符串时,直接返回右边部分。

foo = "foo"
p foo["bar"] = "baz"
p foo

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   "baz"
   "foo"
=> -:2:in `[]=': string not matched (IndexError)
        from -:2
   ruby 1.6.7 (2002-07-30) [i586-linux]
2002-06-03 sprintf()

用"%d"把参数变为整数时,使用与Integer相同的规则。

p sprintf("%d", nil)

=> -:1:in `sprintf': no implicit conversion from nil (TypeError)
        from -:1
   ruby 1.6.7 (2002-03-01) [i586-linux]

=> ruby 1.6.7 (2002-07-30) [i586-linux]
   "0"
2002-05-23 -* 选项(?)

以前,为了兼顾那些使用

#! ruby -*- mode: ruby -*-

这种Emacs'-*-'的脚本,而特别规定:忽略-*以后的部分(将其看作是不进行任何操作的选项),现在已经取消了这种特别设定。若想设定Emacs的'-*-'时,应该写在第2行。[ruby-dev:17193]

ruby '-*' -v
=> ruby 1.6.7 (2002-03-01) [i586-linux]

=> ruby: invalid option -*  (-h will show valid options)
2002-05-22 parsedate

版本升级[ruby-dev:17171]

2002-05-22 -T 选项

以前,若在ruby的命令行选项-T后不留空格地添加其他选项时,-T后面的选项将被忽略。现在,-T后面的非数字部分都被看作是选项(与-0选项相同) [ruby-dev:17179]

ruby -Tv  # -v が無効 (ruby 1.6.7 (2002-03-01) [i586-linux])

=> ruby: No program input from stdin allowed in tainted mode (SecurityError)

=> ruby 1.6.7 (2002-07-30) [i586-linux]
2002-05-20 IO#close

若对双向管道dup进行close_write时,则会引发错误。 [ruby-dev:17155]

open("|-","r+") {|f|
  if f
    f.dup.close_write
  else
     sleep 1
  end
}

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   -:3:in `close_write': closing non-duplex IO for writing (IOError)
        from -:3
        from -:1:in `open'
        from -:1


=> ruby 1.6.7 (2002-07-30) [i586-linux]
2002-05-02 Regexp.quote

# 已经变为back slash quote。主要是为了能将quote中的正则表达式正确嵌入//x。[ruby-bugs-ja:PR#231]

p Regexp.quote("#")

p /a#{Regexp.quote("#")}b/x =~ "ab"

=> -:3: warning: ambiguous first argument; make sure
   ruby 1.6.7 (2002-03-01) [i586-linux]
   "#"
   0

=> -:3: warning: ambiguous first argument; make sure
   ruby 1.6.7 (2002-07-30) [i586-linux]
   "\\#"
   nil
2002-04-29: rb_find_file()

在$SAFE >= 4的情况下,若没有指定绝对路径的话,则会引发SecurityError异常。

2002-04-26: Regexp.quote

[ruby-bugs-ja:PR#231]

p Regexp.quote("\t")

p /a#{Regexp.quote("\t")}b/x =~ "ab"

=> -:3: warning: ambiguous first argument; make sure
   ruby 1.6.7 (2002-03-01) [i586-linux]
   "\t"
   0

=> -:3: warning: ambiguous first argument; make sure
   ruby 1.6.7 (2002-05-04) [i586-linux]
   "\\t"
   nil
2002-04-20: Regexp#inspect

带/x标识的正则表达式对象的inspect把换行变成了\n。[ruby-bugs-ja:PR#225]

p /a
        b/x

=> -:1: warning: ambiguous first argument; make sure
   ruby 1.6.7 (2002-03-01) [i586-linux]
   /a\n                b/x

=> -:1: warning: ambiguous first argument; make sure
   ruby 1.7.2 (2002-04-24) [i586-linux]
   /a
                   b/x
2002-04-19: 结束时的相关处理

以前在下列脚本中,需要发送2次信号才能结束。现在该问题已解决。[ruby-bugs-ja:PR#223]

trap(:TERM, "EXIT")

END{
  puts "exit"
}

Thread::start{ Thread::stop }
sleep
2002-04-17: Regexp#inspect

[ruby-bugs-ja:PR#222]

p %r{\/}

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   /\\//

=> ruby 1.6.7 (2002-05-04) [i586-linux]
   /\//
2002-04-15: pack('U')

已经修复了无法使用unpack('U')来还原pack('U')的bug。(unpack按照字符单位进行处理,而并非以前的字节单位) [ruby-bugs-ja:PR#220]

p [128].pack("U")
p [128].pack("U").unpack("U")

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   "\302\200"
   [0]

=> ruby 1.6.7 (2002-05-04) [i586-linux]
   "\302\200"
   [128]
2002-04-11: IO#write

检测socket或管道中的EPIPE时,有时会出现失败的情况。[ruby-dev:16849]

2002-04-11: cgi/session.rb (*文档中未出现*)

support for multipart form.

2002-04-10: Object#remove_instance_variable

若指定的实例变量尚未定义时,则引发NameError异常。[ruby-bugs-ja:PR#216]

Object.new.instance_eval {
  p remove_instance_variable :@foo
}
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   nil

=> -:2:in `remove_instance_variable': instance variable @foo not defined (NameError)
   ruby 1.6.7 (2002-04-10) [i586-linux]
2002-04-04: Integer#step

以前,若将第二参数设为小于1的数时,它会被看作为0,进而引发错误。

1.step(2, 0.1) {|f| p f }

=> -:1:in `step': step cannot be 0 (ArgumentError)
        from -:1
   ruby 1.6.7 (2002-03-01) [i586-linux]

=> ruby 1.6.7 (2002-04-10) [i586-linux]
   1
   1.1
    :
   1.9
2002-04-01: $~

修复了无法将nil赋值给$~的bug。[ruby-dev:16697]

/foo/ =~ "foo"
p $~
$~ = nil
p $~
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   #<MatchData:0x401b1be4>
   -:3: wrong argument type nil (expected Match) (TypeError)
                                          ^^^^^ MatchData的错误
=> ruby 1.6.7 (2002-04-04) [i586-linux]
   #<MatchData:0x401b1c98>
   nil
2002-03-25 BasicSocket.do_not_reverse_lookup

在$SAFE > 3的情况下,无法设定值。[ruby-dev:16554]

2002-03-23 IO#read

修复了File#read等无法读取大小为0的有内容文件(在Linux的/proc文件系统中会发生这种情况)的bug。

p File.open("/proc/#$$/cmdline").read

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   ""

=> ruby 1.6.7 (2002-03-29) [i586-linux]
   "ruby-1.6\000-v\000-"
2002-03-22 module_eval

在module_eval的块中,常数和类变量的作用域不再变化。[ruby-dev:17876]

class Foo
  FOO = 1
  @@foo = 1
end

FOO = 2
@@foo = 2

Foo.module_eval { p FOO, @@foo }

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   1
   1

=> ruby 1.6.7 (2002-03-29) [i586-linux]
   2
   2
2002-03-22 net/http.rb

以前,Net::HTTP.new在不带块的时候返回nil。 [ruby-bugs-ja:PR#214]

一般认为会逐渐取消net/protocol.rb,该bug好像是在调试时不小心种下的。

2002-03-20 File.expand_path

有时会出现内存释放不彻底的情况。[ruby-bugs:PR#276]

2002-03-18 字符串字面值

在#{..}等结构中,有时会出现汉字代码处理不全的现象。[ruby-list:34478]

#! ruby -Ks
p a = "#{"表"}"
=> -:1: compile error in string expansion (SyntaxError)
   -:1: unterminated string meets end of file
   ruby 1.6.7 (2002-03-15) [i586-linux]
=> ruby 1.6.7 (2002-03-19) [i586-linux]
   "表"

#! ruby -Ks
p %[评价]
=> -:2: parse error
           p %[评价]
                   ^
   ruby 1.6.7 (2002-03-15) [i586-linux]

=> ruby 1.6.7 (2002-03-19) [i586-linux]
   "评价"
2002-03-16 $~

以前,若正则表达式方法没有在内部进行匹配操作时,将不会清除$~ 的状态。[ruby-bugs-ja:PR#208]

/foo/ =~ "foo"
/foo/ =~ nil
p $~

/foo/ =~ "foo"
$_ = nil; ~"foo"
p $~

/foo/ =~ "foo"
"foo".index(/bar/, 4)
p $~

/foo/ =~ "foo"
"foo".rindex(/bar/, -4)
p $~

=> ruby 1.6.7 (2002-03-06) [i586-linux]
   #<MatchData:0x401b1be4>
   #<MatchData:0x401b198c>
   #<MatchData:0x401b1644>
   #<MatchData:0x401b1414>
=> ruby 1.6.7 (2002-03-19) [i586-linux]
   nil
   nil
   nil
   nil
2002-03-14 扩展库的autoload

无法对扩展库进行autoload。[ruby-dev:16379]

autoload :Fcntl, "fcntl"
require "fcntl"

=> -:2:in `require': uninitialized constant Fcntl (NameError)
        from -:2
   ruby 1.6.7 (2002-03-01) [i586-linux]

=> ruby 1.6.7 (2002-03-15) [i586-linux]
2002-03-13 getopts.rb

refine. [ruby-dev:16193], [ruby-dev:16213]

2002-03-11 正则表达式中的8进制代码

以前,在正则表达式中的\nnn形式的8进制表示法中,只有开头是0时,才允许4位数。[ruby-bugs-ja:PR#207]

p /\0001/ =~ "\0001"   # equivalent to "\0" + "1"
=> -:1: warning: ambiguous first argument; make sure
   ruby 1.6.7 (2002-03-01) [i586-linux]
   nil
=> -:1: warning: ambiguous first argument; make sure
   ruby 1.6.7 (2002-03-15) [i586-linux]
   0
2002-03-11 trap

[ruby-bugs-ja:PR#206]

trap('EXIT','Foo')
=> -:1: [BUG] Segmentation fault
   ruby 1.6.7 (2002-03-01) [i586-linux]
=> ruby 1.6.7 (2002-03-15) [i586-linux]
2002-03-10 方法的返回值

下列方法的返回值已被修正。[ruby-bugs-ja:PR#205]

  • each_with_index返回self(以前是nil)
  • Process.setpgrp返回不定值。
  • ljust, rjust, center返回已dup的字符串
2002-03-08 class variable

[ruby-talk:35122]

class C
  class << self
    def test
      @@cv = 5
      p @@cv
    end
  end

  test
end
=> -:5:in `test': uninitialized class variable @@cv in C (NameError)
        from -:9
   ruby 1.6.7 (2002-03-01) [i586-linux]

=> ruby 1.6.6 (2001-12-26) [i586-linux]
   5
2002-03-03 Marshal.load

以前,Marshal.load一直调用1.7的Proc#yield方法。[ruby-dev:16178]

Marshal.load(Marshal.dump('foo'), proc {|o| p o})
=> -:1:in `load': undefined method `yield' for #<Proc:0x401b1b30> (NameError)
        from -:1
   ruby 1.6.7 (2002-03-01) [i586-linux]

=> ruby 1.6.6 (2001-12-26) [i586-linux]
   "foo"

1.6.6 (2001-12-26) -> 1.6.7 (2002-03-01)

2002-02-20 true/false/nil的特殊方法定义

可以通过定义特殊类的方法来为这些伪变量定义特殊方法。

class <<true
  def foo
   "foo"
  end
end
p true.foo
=> -:1: no virtual class for true (TypeError)
   ruby 1.6.6 (2001-12-26) [i586-linux]

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   "foo"
time.rb, URI

已添加。

Ruby/Tk

修复bug,增加功能[ruby-dev:16139],[ruby-dev:16153]。

数值字面值的`_'

重新制定`_'的使用规则,统一了String#hex等数值变换方法的行为规则。[rubyist:1018], [ruby-dev:15684], [ruby-dev:15757]

include

不会递归地对模块进行include操作。

module Foo; end
module Bar; include Foo; end
module Foo; include Bar; end

p Foo.ancestors

=> ruby 1.6.6 (2001-12-26) [i586-linux]
   [Foo, Bar, Foo]

=> -:3:in `append_features': cyclic include detected (ArgumentError)
        from -:3:in `include'
        from -:3
   ruby 1.6.6 (2002-01-28) [i586-linux]
方法的返回值

修正了下列方法的返回值。 [ruby-bugs-ja:PR#182], [rubyist:1016]

  • Hash#default= 返回右边部分(以前返回self)。
  • Dir#pos= 返回右边部分(以前返回self)。 (Dir#seek仍然返回self)
  • Dir.glob 带块时返回nil(以前返回false)
  • IO#close 遇到已关闭的IO则引发IOError。
  • IO#each_byte 返回self(以前返回nil)
rb_define_module_under()

以前,若C函数 rb_define_module_under()定义模块时遇到了已定义的同名常数的话就会失败。[ruby-talk:30203]

Constants = 1
require 'syslog'
p Syslog::Constants

=> -:2:in `require': Syslog::Fixnum is not a module (TypeError)
        from -:2
   ruby 1.6.6 (2001-12-26) [i586-linux]

=> ruby 1.6.6 (2002-01-07) [i586-linux]
   Syslog::Constants

因为这个bug的问题,可能最近就会放出1.6.7[ruby-talk:30387](好像不是这样。因此使用1.6.6的stable-snapshot的用户需要特别注意。因为2002/1/30的下列变更(ChangeLog)

  • re.c (rb_reg_search): should set regs.allocated.

的原因,将导致内存不足。2002/2/13以后的修正版解决了这个问题)。

1.6.5 (2001-09-19) -> 1.6.6 (2001-09-19)

Syslog

已添加。

CGI

针对Netscape(版本是?)的bug进行了处理 [ruby-list:32089]

Time#localtime
Time#gmtime

可以调用一次已冻结的Time 对象。

t = Time.new.freeze
p t.gmtime
p t.localtime

=> -:2:in `gmtime': can't modify frozen Time (TypeError)
        from -:2
   ruby 1.6.5 (2001-09-19) [i586-linux]

=> ruby 1.6.5 (2001-11-01) [i586-linux]
   Mon Nov 05 18:08:34 UTC 2001
   -:3:in `localtime': can't modify frozen Time (TypeError)
        from -:3
File::SEPARATOR
File::ALT_SEPARATOR
File::PATH_SEPARATOR
RUBY_PLATFORM
RUBY_RELEASE_DATE
RUBY_VERSION

上述各项已变为被freeze的字符串。

p File::SEPARATOR.frozen?
p File::ALT_SEPARATOR.frozen?
p File::PATH_SEPARATOR.frozen?

=> ruby 1.6.5 (2001-09-19) [i586-linux]
   false
   false
   false

=> ruby 1.6.5 (2001-11-01) [i586-linux]
   true
   false  # 因为运行环境是Linux,所以ALT_SEPARATOR是nil
   true
Integer[nth]

以前,若遇到大索引值就会引发异常。 [ruby-bugs-ja:PR#114]

p(-1[10000000000])

=> -:1:in `[]': bignum too big to convert into `int' (RangeError)
        from -:1
   ruby 1.6.5 (2001-09-19) [i586-linux]

=> ruby 1.6.5 (2001-11-01) [i586-linux]
   1

不能对整数的负索引返回0。?[ruby-bugs-ja:PR#122]

p(-1[-1])

=> ruby 1.6.5 (2001-09-19) [i586-linux]
   1
=> ruby 1.6.5 (2001-11-01) [i586-linux]
   1
Numeric#remainder

[ruby-bugs-ja:PR#110]

p( 3.remainder(-3))
p(-3.remainder(3))

=> ruby 1.6.5 (2001-09-19) [i586-linux]
   3
   -3
=> ruby 1.6.5 (2001-11-01) [i586-linux]
   0
   0
END { ... }

以前,不能运行END块中的END块。 [ruby-bugs-ja:PR#107]

END {
  p 1
  END { p 2 }
}

=> ruby 1.6.5 (2001-09-19) [i586-linux]
   1

=> ruby 1.6.5 (2001-11-01) [i586-linux]
   1
   2
String#succ

[ruby-talk:22557]

p "***".succ
p "*".succ
p sprintf("%c", 255).succ
p sprintf("*%c", 255).succ
p sprintf("**%c", 255).succ

=> ruby 1.6.5 (2001-09-19) [i586-linux]
   "**+"
   "\001+"
   "\001\000"
   "\001+\000"
   "*+\000"

=> ruby 1.6.5 (2001-11-01) [i586-linux]
   "**+"
   "+"
   "\001\000"
   "+\000"
   "*+\000"
method_missing

以前,下列内容被Segmentation Fault。[ruby-dev:14942]

Module::constants.each {|c|
  c = eval c
  if c.instance_of?(Class)
    p c
    c.instance_methods.each {|m|
      c.module_eval "undef #{m};"
    }
    c.module_eval {undef initialize}
  end
}

=> ruby 1.6.5 (2001-09-19) [i586-linux]
   NotImplementedError
   MatchData
   Exception
   Numeric
   MatchData
   Segmentation fault

=> ruby 1.6.5 (2001-10-15) [i586-linux]
   MatchData
   NotImplementedError
   FloatDomainError
   LoadError
   Float
   Binding
   SignalException
   Module
   -:6:in `method_missing': stack level too deep (SystemStackError)
%q(...)

在使用%表示法的字面值中,不能将英文字母和数字用作切分字符。

p %q1..1
=> ruby 1.6.5 (2001-10-10) [i586-linux]
   ".."
=> -:1: unknown type of %string
        p %q1..1
             ^
   ruby 1.6.5 (2001-10-15) [i586-linux]
String#=~

调用String#=~时,若两边都是字面值的话,为了提升速度而禁止进行方法调用。(实际上,此前就曾考虑过这么做,但因为出现了bug而未能禁止方法调用(不是String#=~,而是Regexp#=~))

class String
  def =~(arg)
    ["String#=~", self, arg]
  end
end

class Regexp
  def =~(arg)
    ["Regexp#=~", self, arg]
  end
end

p "foo" =~ /foo/
p "foo" =~ Regexp.new("foo")

=> -:2: warning: discarding old =~
   -:8: warning: discarding old =~
   ruby 1.6.5 (2001-09-19) [i586-linux]
   ["Regexp#=~", /foo/, "foo"]
   ["String#=~", "foo", /foo/]

=> -:2: warning: discarding old =~
   -:8: warning: discarding old =~
   ruby 1.6.5 (2001-10-10) [i586-linux]
   0
   ["String#=~", "foo", /foo/]

(有时会对内部方法进行这种最优化设置,因此可能导致重定义方法无效的情况,而确切地说,您应该先判断某方法是否已被重定义,然后再选择是否进行最优化)

class 定义

以前,若显式地使用一个不同的超类来重定义某个已定义的类时,则会忽略指定的超类。[ruby-bugs-ja:PR#87]

class A
  p self.id
end
class A < String
  p self.id
  p self.superclass
end

=> ruby 1.6.5 (2001-09-19) [i586-linux]
   537760880
   -:4: warning: already initialized constant A
   537757180
   Object
=> ruby 1.6.5 (2001-10-10) [i586-linux]
   537760960
   -:4: warning: already initialized constant A
   537757200
   String
%w(...)

以前,语法解释器会将数组字面值 %w(...)误判为字符串字面值,从而导致下列异常情况。[ruby-bugs-ja:PR#91]

%w!a! "b" 
=> -:1: tried to allocate too big memory (NoMemoryError)
   ruby 1.6.5 (2001-09-19) [i586-linux]

=> -:1: parse error
       %w!a! "b" 
                ^
   ruby 1.6.5 (2001-10-10) [i586-linux]
Thread

以前存在下列bug:Thread#status对aborting状态返回"run",而Thread#priority = val会返回self而不是val。现已解决这些问题。[rubyist:0820], [ruby-dev:14903]

Marshal

不能dump无名的类/模块。

p Marshal.dump(Class.new)

=> ruby 1.6.4 (2001-06-04) [i586-linux]
   "\004\005c\031#<Class 0lx401a6b44>"

=> -:1:in `dump': can't dump anonymous class #<Class 0lx401ab980> (ArgumentError)
        from -:1
   ruby 1.6.5 (2001-10-05) [i586-linux]
UNIXSocket#addr

以前,UNIXSocket#addr会返回一些垃圾信息(在BSD中如何呢?)。 [ruby-bugs-ja:PR#85]

# server
require 'socket'
File.unlink("/tmp/sss")
sock = UNIXServer.new("/tmp/sss").accept

# client
require 'socket'
sock = UNIXSocket.new("/tmp/sss").addr

=> ["AF_UNIX", "\031((\306\031(\010"]

=> ["AF_UNIX", ""]
???

[ruby-talk:21722]

class Ptr

def initialize(obj) @obj = obj end
def []=() @obj = obj end
def []() @obj end

end module Kernel

def _ptr() Ptr.new(self) end

end

def foo(int)

int[] += 1

end x = 1._ptr foo(x) puts x[]

=> -:11: [BUG] Segmentation fault

ruby 1.6.5 (2001-09-19) [i586-linux]

=> -:11:in `[]=': wrong # of arguments(1 for 0) (ArgumentError)

from -:11:in `foo'
from -:14
ruby 1.6.5 (2001-10-05) [i586-linux]
Subclass of String and Array

以前,在String, Array的子类中调用某些特定方法时,就会变成String, Array。

class Foo < String
end
p Foo.new("").type
p Foo.new("foo")[0,0].type              # String ???
p Foo.new("foo")[1,1].type
p Foo.new("foo").succ.type
p Foo.new("foo").reverse.type
p((Foo.new("foo") * 5).type)
p Foo.new("foo").gsub(/foo/, "bar").type
p Foo.new("foo").sub(/foo/, "bar").type
p Foo.new("foo").ljust(10).type
p Foo.new("foo").rjust(10).type
p Foo.new("foo").center(10).type

=> ruby 1.6.5 (2001-09-19) [i586-linux]
   Foo
   String
   String
   String
   String
   String
   String
   Foo
   String
   String
   String

=> ruby 1.6.5 (2001-10-05) [i586-linux]
   Foo
   String
   Foo
   Foo
   Foo
   Foo
   Foo
   Foo
   Foo
   Foo
   Foo

class Bar < Array
end
bar = Bar.new
p bar.type
p bar.push(1,2,3)
p bar.type
p bar[0,0].type            # => Array ???
p bar[0,1].type
p ((bar * 5).type)

=> -:9: warning: p (...) interpreted as method call
   ruby 1.6.5 (2001-09-19) [i586-linux]
   Bar
   [1, 2, 3]
   Bar
   Array
   Array
   Array
=> -:9: warning: p (...) interpreted as method call
   ruby 1.6.5 (2001-10-05) [i586-linux]
   Bar
   [1, 2, 3]
   Bar
   Array
   Bar
   Bar

1.6.4 (2001-06-04) -> 1.6.5 (2001-09-19)

$_, $~, if a..b

以前,在函数中使用Thread#run时,与该线程共享scope的父线程中的$_, $~会被子线程所覆盖。[ruby-dev:14743]

def foo(t)
  t.run
end

t = Thread.start do
  t = $_= "sub"
  loop{Thread.stop;puts "sub:#$_"}
end

$_ = "main"
t.run                   # => sub:sub
puts "main:#$_"         # => main:main
foo(t)                  # => sub:sub
puts "main:#$_"         # => main:sub
=> ruby 1.6.4 (2001-06-04) [i586-linux]
   sub:sub
   main:main
   sub:sub
   main:sub
=> ruby 1.6.5 (2001-09-19) [i586-linux]
   sub:sub
   main:main
   sub:sub
   main:main
net/telnet.rb

有时,当Net::Telnet连接到特定的端口之后,就失去反应。 [ruby-list:31303]

CGI#header

以前,在下述脚本中,TEXT_PLAIN会被改写成"text/plain; charset=iso-8859-1"。 [ruby-dev:14716]

require 'cgi'

TEXT_PLAIN = "text/plain"

cgi = CGI.new
print cgi.header("type" => TEXT_PLAIN,
                 "charset" => "iso-8859-1")
printf("TEXT_PLAIN: %s\n", TEXT_PLAIN)

=> ruby 1.6.4 (2001-06-04) [i586-linux]
   Content-Type: text/plain; charset=iso-8859-1
   ^M
   TEXT_PLAIN: text/plain; charset=iso-8859-1
   TEXT_PLAIN: text/plain

=> ruby 1.6.5 (2001-09-19) [i586-linux]
   Content-Type: text/plain; charset=iso-8859-1
   ^M
   TEXT_PLAIN: text/plain
Dir.chdir

在尚未定义HOME或LOGDIR时,若不带参数地调用Dir.chdir的话,就会引发ArgumentError异常

ENV['HOME'] = nil ENV['LOGDIR'] = nil Dir.chdir => -:3:in `chdir': Bad address (Errno::EFAULT)

from -:3
ruby 1.6.4 (2001-08-26) [i586-linux]

=> -:3:in `chdir': HOME/LOGDIR not set (ArgumentError)

from -:3
ruby 1.6.5 (2001-09-19) [i586-linux]
Dir.glob

以前,下列代码会引起死循环。

Dir.mkdir("test?") rescue nil
p Dir.glob("test?/*")
=> ruby 1.6.5 (2001-09-19) [i586-linux]
   []
jcode.rb

修改了若干bug。[ruby-list:31238]

Dir.glob

Dir.glob("*/**/*")会重复返回子目录中的文件。 [ruby-dev:14576]

Dir.mkdir('foo') rescue nil
Dir.mkdir('foo/bar') rescue nil
p Dir.glob('*/**/*')

=> ruby 1.6.4 (2001-06-04) [i586-linux]
   ["foo/bar", "foo/bar"]

=> ruby 1.6.4 (2001-08-26) [i586-linux]
   ["foo/bar"]
UnboundMethod#bind

无法bind模块的UnboundMethod对象。 [rubyist:0728]

module Foo
  def foo
    :foo
  end
end

class Bar
  include Foo
end

m = Foo.instance_method :foo
p m.bind(Bar.new).call

=> ruby 1.6.4 (2001-06-04) [i586-linux]
   -:12:in `bind': first argument must be an instance of Foo (TypeError)
        from -:12

=> ruby 1.6.4 (2001-08-23) [i586-linux]
   :foo
内部类的替换

对内部类/模块进行赋值时,会出现警告。

Array = nil
p Array
=> ruby 1.6.4 (2001-06-04) [i586-linux]
   nil

=> -:1: warning: already initialized constant Array
   ruby 1.6.4 (2001-08-23) [i586-linux]
   nil
Regexp

以前,若反向参考中的数字大于括号数量时,则会匹配任何内容。[ruby-list:30975]

p /(foo)\2/ =~ "foobar"
=> ruby 1.6.4 (2001-06-04) [i586-linux]
   0
=> ruby 1.6.4 (2001-08-23) [i586-linux]
   nil
TCPSocket.open

修复了Cygwin中TCPSocket.open 时常出错(Errno::EINVAL, EALREADY)的问题。(1.6.4 20010712以后) [ruby-talk:9939], [ruby-talk:16632], [ruby-list:24702], [ruby-list:27805], [ruby-list:30512] 等等

lib/resolv.rb, lib/resolv-replace.rb

添加。主要是为了在ruby的resolver(DNS解析)和Socket相关的类中使用该库而设立。

在ruby的resovler中,timeout.rb的控制是有效的(即,在域名解析过程中可以进行Thread的切换)

require 'resolv'
p Resolv.new.getaddress("www.ruby-lang.org").to_s

=> /usr/local/lib/ruby/1.6/resolv.rb:160: warning: timeout (...) interpreted as method call
   /usr/local/lib/ruby/1.6/resolv.rb:55: warning: instance variable @initialized not initialized
   /usr/local/lib/ruby/1.6/resolv.rb:113: warning: instance variable @initialized not initialized
   /usr/local/lib/ruby/1.6/resolv.rb:392: warning: instance variable @initialized not initialized
   ruby 1.6.4 (2001-08-23) [i586-linux]
   "210.251.121.214"
Digest 模块

SHA1, MD5被替换成Digest::SHA1, Digest::MD5。 另外,还新增了Digest::SHA256, Digest::SHA384, Digest::SHA512, Digest::RMD160。

require 'digest/md5'
include Digest

md = MD5.new
md << "abc"
puts md

puts MD5.hexdigest("123")
Struct

以前,可以修改已被冻结的结构体对象。另外,当$SAFE = 4时,则禁止进行修改操作。[ruby-talk:19167]

cat = Struct.new("Cat", :name, :age, :life)
a = cat.new("cat", 12, 7).freeze
a.name = "dog"
p a
=> ruby 1.6.4 (2001-06-04) [i586-linux]
   #<Struct::Cat name="dog", age=12, life=7>
=> ruby 1.6.4 (2001-08-06) [i586-linux]
   -:4:in `name=': can't modify frozen Struct (TypeError)
        from -:4

cat = Struct.new("Cat", :name, :age, :life)
a = cat.new("cat", 12, 7)
Thread.new do
   abort_on_exception = true
   $SAFE = 4
   a.life -= 1
end.join
p a.life
=> ruby 1.6.4 (2001-06-04) [i586-linux]
   6
=> ruby 1.6.4 (2001-08-06) [i586-linux]
   -:6:in `life=': Insecure: can't modify Struct (SecurityError)
        from -:3:in `join'
        from -:3
String#rindex

将正则表达式传给rindex时,则会出现bug。[ruby-dev:13843] (该bug出现在1.6.4 版本之后)

p "foobar".rindex(/b/)
=> ruby 1.6.4 (2001-06-04) [i586-linux]
   3

=> ruby 1.6.4 (2001-06-19) [i386-freebsd5.0]
   nil

=> ruby 1.6.4 (2001-08-06) [i586-linux]
   3
require

以前,若把以~开头的文件名传给require时必须带上扩展名,否则无法进行加载。[ruby-dev:13756]

$ echo p __FILE__ > ~/a.rb
$ ruby17 -v -r~/a -e0
ruby 1.7.1 (2001-07-03) [i686-linux]
0: No such file to load -- ~/a (LoadError)
$ ruby16 -v -r~/a -e0
ruby 1.6.4 (2001-07-02) [i686-linux]
0: No such file to load -- ~/a (LoadError)
$ ruby14 -v -r~/a -e0
ruby 1.4.6 (2000-08-16) [i686-linux]
"/home/nobu/a.rb"
String#each_line

以前,无法正确传递污染。[ruby-dev:13755]

"foo\nbar\n".taint.each_line {|v| p v.tainted?}
=> ruby 1.6.4 (2001-06-04) [i586-linux]
   false
   true
=> ruby 1.6.4 (2001-08-06) [i586-linux]
   true
   true
NKF::nkf

以前,无法正确传递污染。[ruby-dev:13754]

require 'nkf'
p NKF.nkf("-j", "a".taint).tainted?

=> ruby 1.6.4 (2001-06-04) [i586-linux]
   false
=> ruby 1.6.4 (2001-08-06) [i586-linux]
   true
ruby -x

指定了-x[directory]选项的话,有时会出现尚未执行脚本就已经结束的情况。[ruby-dev:13752]

attr_*

向accessor传递多余的参数也不会引起错误。 [ruby-dev:13748]

class C
  def initialize
    @message = 'ok'
  end
  attr_reader :message
end
puts C.new.message(1,2,3)

=> ruby 1.6.4 (2001-06-04) [i586-linux]
   ok
=> ruby 1.6.4 (2001-08-06) [i586-linux]
   -:7:in `message': wrong # of arguments(3 for 0) (ArgumentError)
        from -:7
Readline::completion_append_character
Readline::completion_append_character=

添加。GNU Readline库中的rl_completion_append_character变量的accessor。(在GNU readline 2.1之后的版本中才能使用该变量) [ruby-ext:01760]

Socket::Constants

添加了下列socket相关的常数。

SO_PASSCRED
SO_PEERCRED
SO_RCVLOWAT
SO_SNDLOWAT
SO_RCVTIMEO
SO_SNDTIMEO
SO_SECURITY_AUTHENTICATION
SO_SECURITY_ENCRYPTION_TRANSPORT
SO_SECURITY_ENCRYPTION_NETWORK
SO_BINDTODEVICE
SO_ATTACH_FILTER
SO_DETACH_FILTER
SO_PEERNAME
SO_TIMESTAMP
require / $LOAD_PATH

Changed to use a new algorithm to locate a library.

Now when requiring "foo", the following directories are searched for the library in the order listed.

$prefix/lib/ruby/site_ruby/$ver/foo.rb
$prefix/lib/ruby/site_ruby/$ver/foo.so
$prefix/lib/ruby/site_ruby/$ver/$arch/foo.rb
$prefix/lib/ruby/site_ruby/$ver/$arch/foo.so
$prefix/lib/ruby/site_ruby/foo.rb
$prefix/lib/ruby/site_ruby/foo.so
$prefix/lib/ruby/$ver/foo.rb
$prefix/lib/ruby/$ver/foo.so
$prefix/lib/ruby/$ver/$arch/foo.rb
$prefix/lib/ruby/$ver/$arch/foo.so
./foo.rb
./foo.so

The previous behavior had a potential security risk because a foo.rb (if exists) in the current directory is located prior to a foo.so in $prefix/lib/ruby/site_ruby/$ver/$arch.

[ruby-bugs:PR#140], [ruby-ext:01778], [ruby-dev:13659]

lib/sync.rb
lib/mutex_m.rb

Fixed for obj.extend(Sync_m) and obj.extend(Mutex_m).[ruby-dev:13463]

$ ruby -v -rsocket -rmutex_m -e 's=TCPSocket.new("localhost",25); s.extend(Mutex_m)'
ruby 1.6.4 (2001-06-04) [i386-linux]
/usr/lib/ruby/1.6/mutex_m.rb:104:in `initialize': wrong # of arguments (0 for 1) (ArgumentError)
        from /usr/lib/ruby/1.6/mutex_m.rb:104:in `initialize'
        from /usr/lib/ruby/1.6/mutex_m.rb:50:in `mu_extended'
        from /usr/lib/ruby/1.6/mutex_m.rb:34:in `extend_object'
        from -e:1:in `extend'
        from -e:1
$SAFE / load

以前存在以下bug:在1 <= $SAFE <= 3的情况下,当第二参数为true时,即使指定了被污染的对象名,也能进行load()。现在已经修复该bug。[ruby-dev:13481]

$SAFE = 1
filename = "foo"
filename.taint
p load(filename, true)

=> ruby 1.6.4 (2001-06-04) [i586-linux]
   true

=> ruby 1.6.4 (2001-08-06) [i586-linux]
   -:4:in `load': Insecure operation - load (SecurityError)
        from -:4
Regexp

以前,只有后者能匹配成功。[ruby-talk:16233]

puts "OK 1" if /(.|a)bd/ =~ "cxbd"
puts "OK 2" if /(a|.)bd/ =~ "cxbd"

=> ruby 1.6.4 (2001-06-04) [i586-linux]
   OK 2
=> ruby 1.6.4 (2001-08-06) [i586-linux]
   OK 1
   OK 2
Marshal

以前,模块加载时的类型检测中存在错误。修复该错误后,dump format的minor版本号升高1级

p Marshal.dump(Object.new).unpack("CC").join(".")
    => ruby 1.6.4 (2001-06-04) [i586-linux]
       "4.5"
p Marshal.dump(Object.new).unpack("CC").join(".")
    => ruby 1.6.4 (2001-06-11) [i586-linux]
       "4.6"
$SAFE / def

虽然doc/NEWS中有下列内容

Fixed so defining a new method is allowed under $SAFE == 4, which
previously wasn't.

但实际上是行不通的。

$SAFE = 4; def a; end

=> -:1: Insecure operation `(null)' at level 4 (SecurityError)
   ruby 1.6.4 (2001-06-04) [i586-linux]

=> -:1: Insecure: can't define method (SecurityError)
   ruby 1.6.4 (2001-08-06) [i586-linux]

对应的ChangeLog内容如下。

Tue Jun  5 15:16:06 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>

        * eval.c (rb_add_method): should not call rb_secure(), for
          last_func may not be set.

差别如下所示。

@@ -227,10 +227,7 @@ rb_add_method(klass, mid, node, noex)
     NODE *body;

     if (NIL_P(klass)) klass = rb_cObject;
-    if (klass == rb_cObject) {
-       rb_secure(4);
-    }
-    if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
+    if (rb_safe_level() >= 4 && (klass == rb_cObject || !OBJ_TAINTED(klass))) {
        rb_raise(rb_eSecurityError, "Insecure: can't define method");
     }
     if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");

留作日后调查。

IO#ioctl

第2参数也可以接受Bignum了(为了覆盖long int的范围)

1.6.3 (2001-03-19) -> 1.6.4 (2001-06-04)

Hash#replace

以前,在哈希表迭代过程中,若删除某元素后,向其他哈希表中进行replace时,就会Abort。[ruby-dev:13432]

h  = { 10 => 100, 20 => 200 }
h2 = { }

h.each { |k, v|
  if (k == 10)
    h.delete(10)
    h2.replace(h)  # => Abort core dumped
  end
}
$SAFE / File::unlink

在$SAFE >= 2的环境中,即使参数未被污染也不能使用File.unlink。[ruby-dev:13426]

touch foo
ruby -v -e '$SAFE=2;File.unlink("foo")'

=> ruby 1.6.3 (2001-03-19) [i586-linux]
=> ruby 1.6.4 (2001-06-04) [i586-linux]
   -e:1:in `unlink': Insecure operation `unlink' at level 2 (SecurityError)
           from -e:1
Object#untaint

现在不能对已冻结的对象使用untaint方法。[ruby-dev:13409]

a = Object.new
a.taint
a.freeze
a.untaint

=> ruby 1.6.3 (2001-03-19) [i586-linux]
=> ruby 1.6.4 (2001-06-04) [i586-linux]
   -:4:in `untaint': can't modify frozen object (TypeError)
           from -:4
ruby -T4

指定-T4选项时,因为无法修改ARGV导致程序无法运行。[ruby-dev:13401]

touch foo
ruby-1.6.3 -v -T4 foo
=> ruby 1.6.3 (2001-03-19) [i586-linux]
   foo: Insecure: can't modify array (SecurityError)
Regexp

现在,正则表达式中的 \1 .. \9 总是会被解释为反向参考(以前则不同,若有对应的括号则看作反向参考,若没有的话则看作8进制字符代码)。

在正则表达式中指定8进制字符代码时,请使用形如\001这种3位表示法。

另外,若反向参考中没有对应的括号,或者对应的括号中包含反向参考本身的话,则会引起匹配失败。

p /(foo)\2/ =~ "foo\002"
=> ruby 1.6.3 (2001-03-19) [i586-linux]
   0
=> ruby 1.6.4 (2001-06-04) [i586-linux]
   0
=> ruby 1.6.4 (2001-08-23) [i586-linux]
   nil

(如上所示,1.6.4中仍然有bug。大概是在2001-08-23的时候得到了修正[ruby-list:30975])

p /(foo\1)/ =~ "foo"
=> ruby 1.6.3 (2001-03-19) [i586-linux]
   0
=> ruby 1.6.4 (2001-06-04) [i586-linux]
   nil
污染字符串的传播

下列各项都会返回true。[ruby-dev:13340]

# []=
s1 = "abc"
s2 = "cde".taint
s1[0]= s2
p s1.tainted?             # => false

# crypt
s = "abc".taint
p s.crypt("cd").tainted?  # => false

# ljust
s = "abc".taint
p s.ljust(10).tainted?    # => false

# rjust
s = "abc".taint
p s.rjust(10).tainted?    # => false

# center
s = "abc".taint
p s.center(10).tainted?   # => false
rb_yield_0()

以前在C API中使用yield时,1个参数会被当作只包含1个元素的数组来处理。[ruby-dev:13299]

class X
  include Enumerable

  def each(&block)
    block.call(1,2)
    block.call(2,3)
    block.call(3,4)
  end
end

x = X.new
p x.to_a #=> [[1], [2], [3]]

# => ruby 1.6.3 (2001-03-19) [i586-linux]
     [[1], [2], [3]]

# => ruby 1.6.4 (2001-06-04) [i586-linux]
     [1, 2, 3]
$SAFE / alias

当$SAFE = 4时,不允许全局变量使用别名。 [ruby-dev:13287]

Open3::popen3

结束的进程不会调用at_exit。 (将exit修正为exit!) [ruby-dev:13170]

SizedQueue#pop

下列代码不会再导致死锁了。[ruby-dev:13169]

ruby -r thread -e 'q = SizedQueue.new(1); q.push(1);'\
               -e 'Thread.new{sleep 1; q.pop}; q.push(1);'
SizedQueue#max=

以前当max大于当前值时,则会唤起相应的等待线程。但在该处理过程中存在错误。[ruby-dev:13170]

Queue
SizedQueue

在调用Thread#run时,若线程忽然死亡则会引发ThreadError。现在已经针对这个问题进行了相应的处理。[ruby-dev:13194]

Ctrl-C (Interrupt)失效

[ruby-dev:13195]

th1 = Thread.start {
  begin
    Thread.stop
  ensure
    Thread.pass
    Thread.stop
  end
}
sleep 1

(据我所知,在ruby-1.7.0 (2001-05-17) 以后的版本中解决了这个问题,但1.6好像还不行)

Array#&
Array#|
Array#uniq

以前,结果数组中的元素均被冻结,不能修改。[ruby-list:29665]

(%w(foo bar) & %w(foo baz))[0].upcase!
=> -:1:in `upcase!': can't modify frozen string (TypeError)

%w(foo bar bar baz).uniq[0].upcase!
=> -:1:in `upcase!': can't modify frozen string (TypeError)
shell.rb

shell.rb 0.6被添加到标准库中。(文档在doc目录中)

forwardable.rb

forwardable.rb 1.1被添加到标准库中。(文档在doc目录中)

irb.rb & irb-tools

irb和irb-tools分别升级到0.7.4和0.7.1。

夏令时

对夏令时的考虑不周(?) [ruby-bugs-ja:PR#46]

env TZ=America/Managua ruby -e 'p Time.local(1998,12,1,0,59,59)'
=> Mon Nov 30 01:59:59 EST 1998
env TZ=America/Managua ruby -e 'p Time.local(1998,12,1,0,59,59).tv_sec'   
=> 912409199
SIGINFO

对4.4BSD的SIGINFO信号采取了相应的处理措施。[ruby-bugs-ja:PR#45]

Thread.stop中的SEGV

有时会在Thread.stop中发生SEGV。[ruby-dev:13189]

rescue 修饰部分

下列代码在1.6.3中会引起parse error,现在已经修复了该bug。[ruby-dev:13073], [ruby-dev:13292]

raise "" rescue []
raise "" rescue (p "foo"; true)
raise "" rescue -1
raise "" rescue (-1)
Thread

下列代码不会再引起dead lock了。

Thread.start { Thread.stop }
sleep

=> deadlock 0x40199b58: 2:0  - -:1
   deadlock 0x401a2528: 2:4 (main) - -:2
   -:2:in `sleep': Thread: deadlock (fatal)
           from -:2
   ruby 1.6.3 (2001-03-19) [i586-linux]
Module#const_defined?
Module#const_get
Module#const_set

以前,这些方法甚至可以访问常数以外的对象。现在已经修正了该bug [ruby-dev:13019]

Marshal.dump

dump Float时精度由"%.12g"提升到了"%.16g"。 [ruby-list:29349]

Fixnum#[]

好像是修正了在sizeof(long) > sizeof(int)这种系统上的bug。

正则表达式

修正了2个较少见的bug [ruby-talk:13658], [ruby-talk:13744]

retry

在1.6.3中,下列代码不能正常运行[ruby-talk:13957]

def WHILE(cond)
  return if not cond
  yield
  retry
end

i=0
WHILE(i<3) {
  print i
  i+=1
}

ruby 1.6.2 (2000-12-25) [i586-linux]
=> 012

ruby 1.6.3 (2001-03-19) [i586-linux]
=> 0

ruby 1.6.4 (2001-05-02) [i586-linux]
=> 012
File::Stat#size

以前无法正确返回超过1G byte的文件的大小。

File.open("/tmp/1GB", "w") {|f|
  f.seek(2**30-1, 0)
  f.puts
  f.flush
  p f.stat.size
}

# => ruby 1.6.3 (2001-04-03) [i586-linux]
     -1073741824
# => ruby 1.6.4 (2001-04-19) [i586-linux]
     1073741824
Float#modulo, Float#divmod

好像修正了一些问题 [ruby-dev:12718]

ObjectSpace#_id2ref

以前会莫名其妙地返回异常。

malloc的递归调用问题

当stdio在内部调用malloc()时,会破坏其与Thread的兼容性,因此采取了一些补救措施。(通过使用setvbuf(),来避免调用malloc()) [ruby-dev:12795]

File#flock

在File#flock锁定之后,有时会抛出Errno::EACCES异常,而并不会返回false(这种情况出现在没有flock()的系统中)

File::Stat.new(filename)

添加 [ruby-dev:12803]

Bignum#%的计算错误

(再次)修正了导致% 计算错误的bug

a = 677330545177305025495135714080
b = 14269972710765292560
p a % b  #=> 0
p -a % b #=> 

=> ruby 1.6.3 (2001-04-02) [i386-cygwin]
   0
   14269972710765292560

=> ruby 1.6.4 (2001-04-19) [i586-linux]
   0
   0
Marshal

将Bignum进行dump -> load操作之后得到的结果往往与原值不同。

在1.6.3版本之后,共进行了3次相关部分的修改。 请使用stable-snapshot的

ruby 1.6.3 (2001-03-22)

之后的版本。

Universal Naming Convention(UNC) 的支持(win32)

UNC 形式的路径名 (//host/share)得到了支持。使用斜线(`/'),而并非反斜线(`\')。 (其实以前就支持的,难道是修正bug了??)

Dir.glob (win32)

以前,无法对当前目录(./)进行glob。

p Dir["./*.c"]
=> []

1.6.2 -> 1.6.3 (2001-03-19)

do .. end 和 { .. }

以前的版本认定二者的结合度相同,现在修正了这个bug。

在1.6.0到1.6.2之间的版本中,

method v { .. }
method v do .. end

两者之间没有区别。正确的描述详见迭代器部分。

Bignum#% 的计算错误

修正了导致 % 计算错误的bug

ruby-1.6.2 -ve 'p 6800000000%4000000000'
=> ruby 1.6.2 (2000-12-25) [i586-linux]
   -1494967296

ruby-1.6.3 -ve 'p 6800000000%4000000000'
=> ruby 1.6.3 (2001-03-10) [i586-linux]
   2800000000
特殊方法定义

与通常的方法定义一样,也可以指定rescue, ensure部分

obj = Object.new
def obj.foo
rescue
ensure
end
String#count
String#delete
String#squeeze
String#tr_s

可以用'\-'来表示'-'(tr! 等、bang method也是一样的)。以前,只有字符串开头或末尾的'-'才会被看作是'-'。

p "-".tr("a-z",  "+")  # => "-"
p "-".tr("-az",  "+")  # => "+"
p "-".tr("az-",  "+")  # => "+"
p "-".tr('a\-z', "+")  # => "+" # 请注意单引号字符串
p "-".tr("a\\-z", "+") # => "+" # 在""中需要使用二个\
Regexp#==

所有选项都相同的话,则被判定为相同。以前,只要汉字代码选项 和 /i (case-insensitive)相同,就被看作是相同。

%q(), %w()

可以使用反斜线对字面值的末尾字符(`)'等)进行转义。

Dir.glob

"**/"无法找到符号连接了。

String#[]

现在"a"[1,2]会返回""。

p "a"[1,2]
=> ""

这是正确的结果。以前的老版本(1.4.6等)也都是对的。但1.6.0到1.6.2之间的版本则返回nil

p "a"[2,1]返回nil

Object#taint

无法对freeze的对象进行taint操作

obj = Object.new.freeze
obj.taint
=> -:2:in `taint': can't modify frozen object (TypeError)
           from -:2

Previous article: Next article: