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]

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

修复了CygwinTCPSocket.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