ruby version 1.6是稳定版。在该版本中,主要修改了一些bug。
stable-snapshot是稳定版的源代码,且每日更新。
在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
在Cygwin中,有时无法切换Thread。 [ruby-list:36058], [ruby-list:24637]
好像解决了一个Windows中的socket问题。(从原来的邮件中无法得到具体的问题描述,但好像是:虽然可以用select来进行读入,但返回的是空数组) [ruby-talk:40015], [ruby-win32:366]
有时用trap捕获信号时却并没有保存线程的状态,导致被信号中断的线程状态混乱[ruby-talk:40337], [ruby-core:00019]
Queue#pop中存在竞争问题[ruby-dev:17223]
修改了可接受0以下的参数的bug。
在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]
添加(push, pop的别名)。以前尚未定义它们时,调用enq等就会执行超类Queue的enq。
在mswin32版和mingw32版的ruby中,从1.6.6版起就有一个bug:ruby的子进程无法接收环境变量。[ruby-dev:18236]
在使用Bison编译的Ruby中,多次加载库的速度有所提高。(若不使用Bison的话,每次加载时,好像都会显式地执行GC,所以运行速度会下降) [ruby-dev:18145]
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
以前,同时使用Ruby线程和Win32的结构化异常(包括来自Win32 API的callback)的话就会引起故障。现在该bug已被修复。[ruby-win32:273]
以前,只要两个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
以前,若指定了范围之外的字符串的话,有时会返回异常。现在统一返回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
现在可以给第一个参数指定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"]
以前,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"]
以前,无法用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]
有时对负数进行右移位时,就会变成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
添加。
若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]
用"%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"
以前,为了兼顾那些使用
#! 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)
版本升级[ruby-dev:17171]
以前,若在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]
若对双向管道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]
# 已经变为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
在$SAFE >= 4的情况下,若没有指定绝对路径的话,则会引发SecurityError异常。
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
带/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
以前在下列脚本中,需要发送2次信号才能结束。现在该问题已解决。[ruby-bugs-ja:PR#223]
trap(:TERM, "EXIT") END{ puts "exit" } Thread::start{ Thread::stop } sleep
p %r{\/} => ruby 1.6.7 (2002-03-01) [i586-linux] /\\// => ruby 1.6.7 (2002-05-04) [i586-linux] /\//
已经修复了无法使用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]
检测socket或管道中的EPIPE时,有时会出现失败的情况。[ruby-dev:16849]
support for multipart form.
若指定的实例变量尚未定义时,则引发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]
以前,若将第二参数设为小于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
修复了无法将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
在$SAFE > 3的情况下,无法设定值。[ruby-dev:16554]
修复了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-"
在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
以前,Net::HTTP.new在不带块的时候返回nil。 [ruby-bugs-ja:PR#214]
一般认为会逐渐取消net/protocol.rb,该bug好像是在调试时不小心种下的。
有时会出现内存释放不彻底的情况。[ruby-bugs:PR#276]
在#{..}等结构中,有时会出现汉字代码处理不全的现象。[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] "评价"
以前,若正则表达式方法没有在内部进行匹配操作时,将不会清除$~ 的状态。[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
无法对扩展库进行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]
refine. [ruby-dev:16193], [ruby-dev:16213]
以前,在正则表达式中的\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
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]
下列方法的返回值已被修正。[ruby-bugs-ja:PR#205]
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
以前,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"
可以通过定义特殊类的方法来为这些伪变量定义特殊方法。
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"
已添加。
修复bug,增加功能[ruby-dev:16139],[ruby-dev:16153]。
重新制定`_'的使用规则,统一了String#hex等数值变换方法的行为规则。[rubyist:1018], [ruby-dev:15684], [ruby-dev:15757]
不会递归地对模块进行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]
以前,若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)
的原因,将导致内存不足。2002/2/13以后的修正版解决了这个问题)。
已添加。
针对Netscape(版本是?)的bug进行了处理 [ruby-list:32089]
可以调用一次已冻结的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
上述各项已变为被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
以前,若遇到大索引值就会引发异常。 [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
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块。 [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
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"
以前,下列内容被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)
在使用%表示法的字面值中,不能将英文字母和数字用作切分字符。
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#=~时,若两边都是字面值的话,为了提升速度而禁止进行方法调用。(实际上,此前就曾考虑过这么做,但因为出现了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/]
(有时会对内部方法进行这种最优化设置,因此可能导致重定义方法无效的情况,而确切地说,您应该先判断某方法是否已被重定义,然后再选择是否进行最优化)
以前,若显式地使用一个不同的超类来重定义某个已定义的类时,则会忽略指定的超类。[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(...)误判为字符串字面值,从而导致下列异常情况。[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]
以前存在下列bug:Thread#status对aborting状态返回"run",而Thread#priority = val会返回self而不是val。现已解决这些问题。[rubyist:0820], [ruby-dev:14903]
不能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会返回一些垃圾信息(在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", ""]
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]
以前,在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
以前,在函数中使用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连接到特定的端口之后,就失去反应。 [ruby-list:31303]
以前,在下述脚本中,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
在尚未定义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.mkdir("test?") rescue nil p Dir.glob("test?/*") => ruby 1.6.5 (2001-09-19) [i586-linux] []
修改了若干bug。[ruby-list:31238]
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"]
无法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
以前,若反向参考中的数字大于括号数量时,则会匹配任何内容。[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
修复了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] 等等
添加。主要是为了在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"
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")
以前,可以修改已被冻结的结构体对象。另外,当$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
将正则表达式传给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时必须带上扩展名,否则无法进行加载。[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"
以前,无法正确传递污染。[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
以前,无法正确传递污染。[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
指定了-x[directory]选项的话,有时会出现尚未执行脚本就已经结束的情况。[ruby-dev:13752]
向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
添加。GNU Readline库中的rl_completion_append_character
变量的accessor。(在GNU readline 2.1之后的版本中才能使用该变量) [ruby-ext:01760]
添加了下列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
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.
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
以前存在以下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
以前,只有后者能匹配成功。[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
以前,模块加载时的类型检测中存在错误。修复该错误后,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"
虽然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");
留作日后调查。
第2参数也可以接受Bignum了(为了覆盖long int的范围)
以前,在哈希表迭代过程中,若删除某元素后,向其他哈希表中进行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 >= 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
现在不能对已冻结的对象使用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
指定-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)
现在,正则表达式中的 \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
以前在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 = 4时,不允许全局变量使用别名。 [ruby-dev:13287]
结束的进程不会调用at_exit。 (将exit修正为exit!) [ruby-dev:13170]
下列代码不会再导致死锁了。[ruby-dev:13169]
ruby -r thread -e 'q = SizedQueue.new(1); q.push(1);'\ -e 'Thread.new{sleep 1; q.pop}; q.push(1);'
以前当max大于当前值时,则会唤起相应的等待线程。但在该处理过程中存在错误。[ruby-dev:13170]
在调用Thread#run时,若线程忽然死亡则会引发ThreadError。现在已经针对这个问题进行了相应的处理。[ruby-dev:13194]
th1 = Thread.start { begin Thread.stop ensure Thread.pass Thread.stop end } sleep 1
(据我所知,在ruby-1.7.0 (2001-05-17) 以后的版本中解决了这个问题,但1.6好像还不行)
以前,结果数组中的元素均被冻结,不能修改。[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 0.6被添加到标准库中。(文档在doc目录中)
forwardable.rb 1.1被添加到标准库中。(文档在doc目录中)
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
对4.4BSD的SIGINFO信号采取了相应的处理措施。[ruby-bugs-ja:PR#45]
有时会在Thread.stop中发生SEGV。[ruby-dev:13189]
下列代码在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)
下列代码不会再引起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]
以前,这些方法甚至可以访问常数以外的对象。现在已经修正了该bug [ruby-dev:13019]
dump Float时精度由"%.12g"提升到了"%.16g"。 [ruby-list:29349]
好像是修正了在sizeof(long) > sizeof(int)这种系统上的bug。
修正了2个较少见的bug [ruby-talk:13658], [ruby-talk:13744]
在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
以前无法正确返回超过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
好像修正了一些问题 [ruby-dev:12718]
以前会莫名其妙地返回异常。
当stdio在内部调用malloc()时,会破坏其与Thread的兼容性,因此采取了一些补救措施。(通过使用setvbuf(),来避免调用malloc()) [ruby-dev:12795]
在File#flock锁定之后,有时会抛出Errno::EACCES异常,而并不会返回false(这种情况出现在没有flock()的系统中)
(再次)修正了导致% 计算错误的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
将Bignum进行dump -> load操作之后得到的结果往往与原值不同。
在1.6.3版本之后,共进行了3次相关部分的修改。 请使用stable-snapshot的
ruby 1.6.3 (2001-03-22)
之后的版本。
UNC 形式的路径名 (//host/share)得到了支持。使用斜线(`/
'),而并非反斜线(`\
')。 (其实以前就支持的,难道是修正bug了??)
以前,无法对当前目录(./)进行glob。
p Dir["./*.c"] => []
以前的版本认定二者的结合度相同,现在修正了这个bug。
在1.6.0到1.6.2之间的版本中,
method v { .. } method v do .. end
两者之间没有区别。正确的描述详见迭代器部分。
修正了导致 % 计算错误的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
可以用'\-'来表示'-'(tr! 等、bang method也是一样的)。以前,只有字符串开头或末尾的'-'才会被看作是'-'。
p "-".tr("a-z", "+") # => "-" p "-".tr("-az", "+") # => "+" p "-".tr("az-", "+") # => "+" p "-".tr('a\-z', "+") # => "+" # 请注意单引号字符串 p "-".tr("a\\-z", "+") # => "+" # 在""中需要使用二个\
所有选项都相同的话,则被判定为相同。以前,只要汉字代码选项 和 /i (case-insensitive)相同,就被看作是相同。
可以使用反斜线对字面值的末尾字符(`)'等)进行转义。
"**/"无法找到符号连接了。
现在"a"[1,2]会返回""。
p "a"[1,2] => ""
这是正确的结果。以前的老版本(1.4.6等)也都是对的。但1.6.0到1.6.2之间的版本则返回nil
。
p "a"[2,1]
返回nil
。
无法对freeze的对象进行taint
操作
obj = Object.new.freeze obj.taint => -:2:in `taint': can't modify frozen object (TypeError) from -:2