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]
#
-:3: wrong argument type nil (expected Match) (TypeError)
^^^^^ MatchData的错误
=> ruby 1.6.7 (2002-04-04) [i586-linux]
#
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]
#
#
#
#
=> 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 # (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 < 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#"
=> -:1:in `dump': can't dump anonymous class # (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]
#
=> 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
* 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
ruby 1.7 特性
ruby version 1.7是开发版。将来可能会删除下列中的部分内容,也可能因为兼容性问题而对其进行修改。
1.7.3 -> 1.8.0 preview1 (2002-12-24)
2002-12-20
profiler.rb [lib] [new]
新增。作为profile.rb的实体将其分离出来。
rb_define_alloc_func() [api] [new]
rb_undef_alloc_func() [api] [new]
新增。用在allocate方法的定义中。 [ruby-dev:19116]
2002-12-18
Regexp#=== [compat]
返回布尔值。
p(/foo/ === "foo")
=> ruby 1.6.8 (2002-12-24) [i586-linux]
0
=> ruby 1.8.0 (2003-03-12) [i586-linux]
true
2002-12-17
defined? [compat]
遇到对属性赋值或对数组元素进行赋值的情况时,返回"assignment"而非"method"。
class Foo
attr_accessor :foo
end
p defined? Foo.new.foo = 1
ary = []
p defined? ary[2] = 1
=> ruby 1.6.8 (2002-12-24) [i586-linux]
"method"
"method"
=> ruby 1.8.0 (2003-03-12) [i586-linux]
"assignment"
"assignment"
2002-12-17
open-uri.rb [lib] [new]
新增
2002-12-14
WindowsCE [platform]
加入了WindowsCE的支持补丁。
2002-12-11
IO#read [compat]
IO#sysread [compat]
向IO#read, IO#sysread新增了第二参数(指定了预先分配好的读入缓冲)
2002-12-10
Thread#terminate [new]
新增。与Thread#kill 相同。
2002-12-07
Process.abort [new]
Process.exit [new]
新增。与abort, exit函数相同。
2002-12-06
Process::Status#pid [new]
新增
2002-12-04
Object#copy_object
改名了,原名为become。(此后,在1.8中又改名为initialize_copy)
2002-11-27
SystemExit#initialize [compat]
增加了参数。
ruby -e 'raise SystemExit.new(2)'
echo $?
# => 2
2002-11-19
Array#transpose [new]
新增
p [[1,2,3],
[4,5,6],
[7,8,9]].transpose
=> ruby 1.7.3 (2002-12-11) [i586-linux]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
2002-11-08
[parser] [experimental]
试验性的修改。
a = 1
p a / 5
=> ruby 1.6.8 (2002-12-24) [i586-linux]
0
=> ruby 1.8.0 (2003-03-12) [i586-linux]
0
a = 1
p a /5
=> -:2: warning: ambiguous first argument; make sure
-:2: unterminated regexp meets end of file
ruby 1.6.8 (2002-12-24) [i586-linux]
=> ruby 1.8.0 (2003-03-12) [i586-linux]
0
2002-11-02
Object#object_id [new]
新增 (Object#id是obsolete)
p Object.new.id
=> ruby 1.6.7 (2002-03-01) [i586-linux]
537730140
=> -:1: warning: Object#id will be deprecated; use Object#object_id
ruby 1.7.3 (2002-12-04) [i586-linux]
537723790
2002-11-02
Fixnum#to_sym [new]
String#to_sym [new]
新增(取消了Symbol#intern)
2002-11-01
Array#zip [new]
Enumerable#zip [new]
新增
p [1,2,3].zip([4,5,6], [7,8,9])
=> ruby 1.7.3 (2002-12-11) [i586-linux]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
p [1,2,3].zip([4,5,6], [7,8,9]) {|v| p v}
=> ruby 1.7.3 (2002-12-11) [i586-linux]
[1, 4, 7]
[2, 5, 8]
[3, 6, 9]
nil
2002-10-30
Module#private_method_defined? [new]
Module#protected_method_defined? [new]
Module#public_method_defined? [new]
Object#methods [change]
Module#instance_methods [change]
[ruby-dev:18606]
增加了Module#private_method_defined?,Module#protected_method_defined?,Module#public_method_defined?
修改了Object#methods, Module#instance_methods(为了与 Module#method_defined?和Module#instance_methods的关系 取得一致)
class Foo
def public_m; end
private
def private_m; end
protected
def protected_m; end
end
foo = Foo.new
m = %w(public_m private_m protected_m)
p m.collect {|_| Foo.method_defined?(_)}
if Foo.respond_to? :public_method_defined?
p m.collect {|_| Foo.public_method_defined?(_)}
p m.collect {|_| Foo.private_method_defined?(_)}
p m.collect {|_| Foo.protected_method_defined?(_)}
end
puts '---'
p m.collect {|_| Foo.instance_methods.member?(_)}
p m.collect {|_| Foo.public_instance_methods.member?(_)}
p m.collect {|_| Foo.private_instance_methods.member?(_)}
p m.collect {|_| Foo.protected_instance_methods.member?(_)}
puts '---'
p m.collect {|_| foo.methods.member?(_)}
p m.collect {|_| foo.public_methods.member?(_)}
p m.collect {|_| foo.private_methods.member?(_)}
p m.collect {|_| foo.protected_methods.member?(_)}
=> ruby 1.6.8 (2002-12-24) [i586-linux]
[true, false, true]
---
[true, false, false]
[true, false, false]
[false, true, false]
[false, false, true]
---
[true, false, false]
[true, false, false]
[false, true, false]
[false, false, true]
=> ruby 1.8.0 (2003-03-09) [i586-linux]
[true, false, true]
[true, false, false]
[false, true, false]
[false, false, true]
---
[true, false, true]
[true, false, false]
[false, true, false]
[false, false, true]
---
[true, false, true]
[true, false, false]
[false, true, false]
[false, false, true]
2002-10-23
[parser] [new]
采用了符号的扩展表示法。[ruby-dev:18537]
p :"foo#{"bar"}"
p :'foo#{"bar"}'
p %s{foo#{"bar"}}
=> ruby 1.7.3 (2002-11-14) [i586-linux]
:foobar
:"foo\#{\"bar\"}"
:"foo\#{\"bar\"}"
2002-10-11
rescue修饰部分 [parser] [change]
修改了rescue修饰部分的优先级。好像是试验性的修改。 (在1.8版本中正式采用了这个修改)。因此
a = b rescue c
不会被解释成
(a = b) rescue c
而是被解释为
a = (b rescue c)
虽然与if修饰部分的优先级有所不同,但它有个好处:如果b发生异常时可以使用c的值。
# 若在以前的版本(1.6)中执行下列代码时,则不会进行赋值
# 只是对变量进行了定义,结果是v等于nil。
v = raise rescue true
p v
=> ruby 1.6.7 (2002-03-01) [i586-linux]
nil
=> ruby 1.7.3 (2002-10-18) [i586-linux]
true
2002-10-02
Object#type [obsolete]
使用它就会出现警告。请您使用Object#class来代替它。
p Object.new.type
=> -:1: warning: Object#type is deprecated; use Object#class
ruby 1.7.3 (2002-10-08) [i586-linux]
Object
2002-09-27
Class#inherited [change]
在类定义表达式的末尾才会调用inherited方法。 [ruby-bugs-ja:PR#342]
def Object.inherited(c)
p "inherited!"
end
class Foo
p "defining Foo"
end
=> ruby 1.6.7 (2002-03-01) [i586-linux]
"inherited!"
"defining Foo"
=> ruby 1.7.3 (2002-10-04) [i586-linux]
"defining Foo"
"inherited!"
2002-09-26
[parser] [compat]
若在方法定义的外侧调用return的话,则会在运行时而非编译时引发错误。
p :doing
return
=> -:2: return appeared outside of method
ruby 1.6.7 (2002-03-01) [i586-linux]
=> ruby 1.7.3 (2002-10-04) [i586-linux]
:doing
-:2: unexpected return
2002-09-13
||= [bug]
以前,使用||=对未定义的变量进行赋值时,会在全局变量中出现警告。另外,在类变量中会引发错误。 [ruby-dev:18278]
local ||= 1
@instance ||= 1
$global ||= 1
@@class ||= 1
=> -:3: warning: global variable `$global' not initialized
-:4: uninitialized class variable @@class in Object (NameError)
ruby 1.6.7 (2002-03-01) [i586-linux]
=> ruby 1.7.3 (2002-09-13) [i586-linux]
2002-09-11
Process.pid (win) [change]
在mswin32版和mingw32版中,ruby会在内部将进程ID变为正数。虽然在NT系列的OS中没有什么变化,但在Win9x系列的OS中,由OS控制的进程ID是负数,所以才将其变为正数。[ruby-dev:18263]
2002-09-11
IO#read, gets ..., etc. [bug]
在对File::NONBLOCK模式的IO进行读入操作时,如果发生EWOULDBLOCK的话,可能会导致读入数据丢失。 [ruby-dev:17855]
在使用Thread的程序中,如果从文件中读出数据并写入socket时,可能会在Socket#write中引发Errno::EINTR,但这种情况极少出现。[ruby-dev:17878], [ruby-core:00444]
2002-09-05
Marshal.dump [marshal] [change]
无法对包含(include)了无名模块的对象进行dump。 [ruby-dev:18186]
class << obj = Object.new
include Module.new
end
Marshal.dump(obj)
=> ruby 1.6.7 (2002-03-01) [i586-linux]
=> -:4:in `dump': can't dump anonymous class # (ArgumentError)
from -:4
ruby 1.7.3 (2002-09-06) [i586-linux]
可以dump包含(include)了有名模块的对象,此时模块的信息被保存到dump format之中。
module M
def foo
p :foo
end
end
class << obj = Object.new
include M
end
p dump = Marshal.dump(obj)
p obj2 = Marshal.load(dump)
class << obj2
p included_modules
end
obj2.foo
=> ruby 1.6.7 (2002-03-01) [i586-linux]
"\004\006o:\vObject\000"
#
[Kernel]
-:14: undefined method `foo' for # (NameError)
=> ruby 1.7.3 (2002-09-06) [i586-linux]
"\004\ae:\006Mo:\vObject\000"
#
[M, Kernel]
:foo
因此将format version由4.7提升到4.8。 (2002-09-17)
2002-09-03
mkmf.rb, extmk.rb [lib] [compat]
开始着手合并extmk.rb和mkmf.rb。extmk.rb将会用到mkmf.rb。相应地对mkmf.rb也作出调整。[ruby-dev:18109]
2002-08-31
ruby interpreter [ruby] [change]
定义规定:类的特殊类的特殊类,就是特殊类本身[ruby-bugs-ja:PR#313]。不太明白(^^;
class << Object
p [self.id, self]
class << self
p [self.id, self]
end
end
=> ruby 1.6.7 (2002-03-01) [i586-linux]
[537771634, Class]
[537742484, Class]
=> ruby 1.7.3 (2002-09-05) [i586-linux]
[537771634, #]
[537771634, #]
另外好像说,对象的特殊类的超类的特殊类 和 对象的特殊类的特殊类的超类是一回事儿[ruby-bugs-ja:PR#324]。更不明白了(^^;;
class << Object.new
class << self.superclass
p [self.id, self]
end
class << self
p [self.superclass.id, self.superclass]
end
end
=> ruby 1.6.7 (2002-03-01) [i586-linux]
[537771634, Class]
[537771644, Class]
=> ruby 1.7.3 (2002-09-05) [i586-linux]
[537771634, #]
[537771634, #]
[ruby-bugs-ja:PR#336]中好像还有些变化 (请参考2002-09-21的ChangeLog。)
2002-08-30
set.rb [lib] [new]
新增
2002-08-27
Object#become
新增(后来改名为copy_object。再后来又改名为initialize_copy)
ary = [1,2,3]
p ary, ary.id
ary.become [3,2,1]
p ary, ary.id
=> ruby 1.7.3 (2002-08-30) [i586-linux]
[1, 2, 3]
537743354
[3, 2, 1]
537743354
ary = [1,2,3]
p ary, ary.id
ary.replace [3,2,1]
p ary, ary.id
=> ruby 1.7.3 (2002-08-30) [i586-linux]
[1, 2, 3]
537743354
[3, 2, 1]
537743354
obj = Object.new
p obj, obj.id
obj.become Object.new
p obj, obj.id
=> ruby 1.7.3 (2002-08-30) [i586-linux]
#
537743354
#
537743354
2002-08-23
ruby interpreter (win32, MinGW) [ruby] [change]
保证了mswin32版ruby 和 MinGW版ruby中的扩展库的兼容性。分别把Config::CONFIG['RUBY_SO_NAME']变更为msvcrt-rubyXX(成为DLL名),把Config::CONFIG['sitearch'](扩展库所在地的路径元素)变更为"i386-msvcrt"。 [ruby-dev:17144], [ruby-dev:18047]
在这次修改中,新增了sitearch(在其他环境中,则与CONFIG['arch']相同)
另外请参考Win32 native版的脚注
2002-08-20
IO#putc [compat]
在各输出方法中,只有putc不使用write方法。 [ruby-dev:18038]
class << foo = STDOUT.dup
def write(s)
p "foo"
end
end
foo.putc("bar")
puts
=> ruby 1.6.7 (2002-03-01) [i586-linux]
b
=> ruby 1.7.3 (2002-09-05) [i586-linux]
"foo"
2002-08-13
Hash#default_proc [new]
新增 [ruby-dev:17966]
2002-08-11
Proc#to_s [compat]
在Proc#to_s 的结果中新增了脚本的源文件名和行号。[ruby-dev:17968]
p Proc.new {
2
3
}.to_s
=> -:2: warning: useless use of a literal in void context
ruby 1.6.7 (2002-03-01) [i586-linux]
"#"
=> -:2: warning: useless use of a literal in void context
ruby 1.7.3 (2002-09-05) [i586-linux]
"#"
2002-08-01
Enumerable#find [change]
不能将字符串指定给参数了。
[1,2,3].find("p :nothing") {|v| v > 5}
=> ruby 1.6.7 (2002-03-01) [i586-linux]
:nothing
=> -:1:in `find': undefined method `call' for "p :nothing":String (NoMethodError)
from -:1
ruby 1.7.2 (2002-08-01) [i586-linux]
另外,若没有找到元素的话,就返回ifnone 的结果。
p [1,2,3].find(proc {:nothing}) {|v| v > 5}
=> ruby 1.6.7 (2002-03-01) [i586-linux]
nil
=> ruby 1.7.2 (2002-08-01) [i586-linux]
:nothing
2002-07-27
Numeric#to_int [new]
Float#to_int [new]
新增。
2002-07-26
rand [compat]
在生成随机数的算法中使用了Mersenne Twister。
2002-07-24
[parser] [compat]
允许对方法定义进行嵌套。
def func1
def func2
p :func2
end
end
func1
func2
=> -:2: nested method definition
ruby 1.6.7 (2002-03-01) [i586-linux]
=> ruby 1.7.3 (2002-09-05) [i586-linux]
:func2
允许在方法定义中出现alias, undef。
def bar
end
def foo
p :foo
undef bar
end
foo
def bar
p :bar
alias foo bar
end
bar
foo
=> -:5: undef within method
-:12: alias within method
ruby 1.6.7 (2002-03-01) [i586-linux]
=> ruby 1.7.3 (2002-09-05) [i586-linux]
:foo
-:10: warning: method redefined; discarding old bar
-:10: warning: overriding global function `bar'
:bar
:bar
在方法定义外侧调用super时,将会在运行时而不是编译时引发错误。
p 1
super
=> -:2: super called outside of method
ruby 1.6.7 (2002-03-01) [i586-linux]
=> ruby 1.7.3 (2002-09-05) [i586-linux]
1
-:2: super called outside of method (NoMethodError)
也许[ruby-dev:16969]中给出了变更的理由。[ruby-dev:17882]
2002-07-19
数值字面值 [compat]
新增了10进制整数字面值的0d前缀。
p 0d10
=> ruby 1.7.3 (2002-09-04) [i586-linux]
10
p 0d10.1
=> -:1: parse error
ruby 1.7.3 (2002-09-04) [i586-linux]
允许使用