ruby参考手册VI

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]

允许使用

你可能感兴趣的:(ruby参考手册VI)