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 #<Module:0x401a871c> (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"
   #<Object:0x401a9630>
   [Kernel]
   -:14: undefined method `foo' for #<Object:0x401a9630> (NameError)
=> ruby 1.7.3 (2002-09-06) [i586-linux]
   "\004\ae:\006Mo:\vObject\000"
   #<Object:0x401a821c>
   [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, #<Class:Object>]
   [537771634, #<Class:Object>]

另外好像说,对象的特殊类的超类的特殊类 和 对象的特殊类的特殊类的超类是一回事儿[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, #<Class:Object>]
   [537771634, #<Class:Object>]

[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]
   #<Object:0x401a9ff4>
   537743354
   #<Object:0x401a9ff4>
   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]
   "#<Proc:0x401ab8b8>"
=> -:2: warning: useless use of a literal in void context
   ruby 1.7.3 (2002-09-05) [i586-linux]
   "#<Proc:0x0x401a87d0@-:2>"

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]

允许使用大写字母。

p 0D10
=> ruby 1.7.3 (2002-09-04) [i586-linux]
   10

但不能像下面这样。

p(/\d10/)
p "\d10"
=> ruby 1.7.3 (2002-09-04) [i586-linux]
   /\d10/
   "d10"

只要字面值允许,Integer()也就允许。

p Integer("0d010")
=> ruby 1.7.3 (2002-09-04) [i586-linux]
   10

p Integer("0d010.1")
=> -:1:in `Integer': invalid value for Integer: "0d010.1" (ArgumentError)
        from -:1
   ruby 1.7.3 (2002-09-04) [i586-linux]

String#to_i、String#oct也是如此

p "0d010".to_i
p "0d010".oct
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   0
   0
=> ruby 1.7.3 (2002-09-04) [i586-linux]
   10
   10

2002-07-18

net/ftp.rb [new]

新增set_socket方法

2002-07-17

数值字面值 [compat]

新增了8进制字面值的0和0o前缀。

p 0o377
=> ruby 1.7.3 (2002-09-04) [i586-linux]
   255

可以使用大写字母。

p 0O377
=> ruby 1.7.3 (2002-09-04) [i586-linux]
   255

不能像下面这样。

p(/\o377/)
p "\o377"
=> ruby 1.7.3 (2002-09-04) [i586-linux]
   /\o377/
   "o377"

只要字面值允许,Integer()也没问题。

p Integer("0o377")
=> -:1:in `Integer': invalid value for Integer: "0o377" (ArgumentError)
        from -:1
   ruby 1.6.7 (2002-03-01) [i586-linux]
=> ruby 1.7.3 (2002-09-04) [i586-linux]
   255

String#to_i、String#oct也是如此

p "0o377".oct
p "0o377".to_i(8)
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   0
   -:2:in `to_i': wrong # of arguments(1 for 0) (ArgumentError)
        from -:2
=> ruby 1.7.3 (2002-09-04) [i586-linux]
   255
   255

2002-07-11

String#scan [change]
String#split [change]
String#sub, String#sub! [change]
String#gsub, String#gsub! [change]
String#~ [change]
String#=~ [change]

若将字符串而非正则表达式传给pattern的话,就直接把它用作匹配模型,而不会将其编译成正则表达式。(准确地讲,不会Regexp.compile(arg)这样处理,而是Regexp.compile(Regexp.quote(arg))这样)

只有str =~ arg中的arg是字符串时,才会执行str.index(arg),它等价于Regexp.compile(Regexp.quote(arg)) =~ str(所以没有设定$~)。

p "aaaa*".scan("a*")
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   ["aaaa", "", ""]
=> -:1: warning: string pattern instead of regexp; metacharacters no longer effective
   ruby 1.7.3 (2002-09-04) [i586-linux]
   ["a*"]

p "aa*aa*aa*".split("a*")
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   ["", "*", "*", "*"]
=> -:1: warning: string pattern instead of regexp; metacharacters no longer effective
   ruby 1.7.3 (2002-09-04) [i586-linux]
   ["a", "a", "a"]

p "aa*".sub('a*', '')
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   "*"
=> -:1: warning: string pattern instead of regexp; metacharacters no longer effective
   ruby 1.7.3 (2002-09-04) [i586-linux]
   "a"

p "aa*aa*aa*aa*".gsub('a*', '')
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   "****"
=> -:1: warning: string pattern instead of regexp; metacharacters no longer effective
   ruby 1.7.3 (2002-09-04) [i586-linux]
   "aaaa"

$_ = "aa*"
p ~"a*"
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   0
=> ruby 1.7.3 (2002-09-04) [i586-linux]
   1

2002-07-03

net/ftp.rb [compat]

getbinaryfile() 的第二参数(本地文件名)变为可选参数。新增get(), put(), binary(),binary = 方法

2002-06-29

双向管道 (win) [compat]

听说加入了支持Win32用的双向管道的补丁 [ruby-win32:185]

2002-06-26

Object#to_a [obsolete]

使用它的话会出现警告消息。(听说已经变成obsolete)

p Object.new.to_a

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   [#<Object:0x401ab8b8>]
=> -:1: warning: default `to_a' will be obsolete
   ruby 1.7.3 (2002-09-02) [i586-linux]
   [#<Object:0x401a88ac>]

2002-06-26

Array() [change]

Array()的参数不再接受nil。 (在ruby 1.8.0 (2003-05-29)中,又开始接受nil了)

p Array(nil)

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   []
=> -:1:in `Array': cannot convert nil into Array (TypeError)
        from -:1
   ruby 1.7.3 (2002-09-02) [i586-linux]

=> ruby 1.8.0 (2003-05-29) [i586-linux]
   []

2002-06-26

%W() [parser]

新增了%W(...) 数组字面值。与%w()不同的是,它可以使用反斜线表示法和展开式。[ruby-dev:15988]

v = "b c"
p %W(a #{v}d\se)

=> ruby 1.7.3 (2002-09-04) [i586-linux]
   ["a", "b cd e"]

2002-06-25

Integer() [change]

在把数值或字符串以外的对象变换为整数时,不再使用to_i,而是使用to_int进行变换。

class << obj = Object.new
  def to_i()   0 end
  def to_int() 1 end
end

p Integer(obj)

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   0
=> ruby 1.7.3 (2002-09-02) [i586-linux]
   1

2002-06-25

NilClass#to_f [new]

新增

p nil.to_f

=> -:1: undefined method `to_f' for nil (NameError)
   ruby 1.6.7 (2002-03-01) [i586-linux]
=> ruby 1.7.3 (2002-09-02) [i586-linux]
   0.0

2002-06-25

Float() [change]

Float()的参数不再接受nil。

p Float(nil)

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   0.0
=> -:1:in `Float': cannot convert nil into Float (TypeError)
        from -:1
   ruby 1.7.3 (2002-09-02) [i586-linux]

2002-06-24

展开式 [parser]

在#{ ... }展开式中,可以书写任何ruby程序,包括字符串分隔符在内。虽然以前也是如此,但此次则明确了规则。也就是说,展开式中的语法规则与外面相同。ruby程序会被正确解析。[ruby-dev:17422]

(1.6 版本中,曾出现过异常的举动)

p "#{ "foo" }"
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   "foo"
=> -:1: warning: bad substitution in string
   -:1: parse error
           p "#{ "foo" }"
                     ^
   ruby 1.6.7 (2002-08-21) [i586-linux]
=> ruby 1.6.8 (2002-12-24) [i586-linux]
   "foo"
=> ruby 1.7.3 (2002-09-02) [i586-linux]
   "foo"

不应该对下列分隔符进行转义。

p "#{ \"foo\" }"
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   "foo"
=> ruby 1.6.7 (2002-08-21) [i586-linux]
   "foo"
=> -:1: warning: escaped terminator '"' inside string interpolation
   ruby 1.7.3 (2002-09-02) [i586-linux]
   "foo"

请注意:展开式中注释并不是从 # 到 } ,而是从 # 到换行。

p "#{ "foo" # comment }"

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   "foo"
=> -:1: parse error
   ruby 1.7.3 (2002-09-02) [i586-linux]


p "#{ "foo" # comment
   }"

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   "foo"
=> ruby 1.7.3 (2002-09-02) [i586-linux]
   "foo"

2002-06-21

[parser] [compat]

字符串字面值中的行首的 __END__ 不再被当作脚本的结束标志了。[ruby-dev:17513]

# p "
#__END__
#"
p eval(%Q(p "\n__END__\n"))
=> -:1: compile error (SyntaxError)
   (eval):1: unterminated string meets end of file
   ruby 1.6.7 (2002-03-01) [i586-linux]
=> ruby 1.7.3 (2002-09-02) [i586-linux]
   "\n__END__\n"
   nil

2002-06-15

?<whitespace> [parser] [change]

?空格、?换行、?TAB 等不再是字面值。若必须使用的话,可以写成 ?\s, ?\n, ?\t 。(请注意,下例中的前半部分使用了双引号) [ruby-bugs-ja:PR#261], [ruby-dev:17446]

p eval("?\t")
p eval("?\n")
p eval("?\v")
p eval("?\f")
p eval("?\r")
p eval("? ")

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   9
   10
   11
   12
   13
   32

=> -:1: compile error (SyntaxError)
   (eval):1: parse error
   ruby 1.7.3 (2002-09-02) [i586-linux]

p eval('?\t')
p eval('?\n')
p eval('?\v')
p eval('?\f')
p eval('?\r')
p eval('?\s')

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   9
   10
   11
   12
   13
   32
=> ruby 1.7.3 (2002-09-02) [i586-linux]
   9
   10
   11
   12
   13
   32

2002-06-11

Borland C++ 支持 [platform]

合并了支持在bcc中编译ruby解释器的补丁。

2002-06-04

Range#max [change]
Range#min [change]
Range#include? [change]
Range#member? [change]

Range#max, Range#min, Range#include? 使用 <=> 方法进行范围计算。[ruby-list:35253], [ruby-dev:17228] (2003-03-18: min, max 变回原样。[ruby-dev:19837])

Range#member? 使用 each 来遍历所有元素并确认是否有member。(与Enumerable#member?相同)

截止1.6,max, min, member? include? 是 Enumerable 的方法,=== 是 Range的方法。在1.7中,max, min, member?, include?, === 都是 Range 的方法,include? 成了 === 的别名。(在1.8中,max, min重新成为 Enumerable 的方法)

因为这些变动导致下列不同。

p((0.1 .. 2.0).include?(1.1))
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   false
=> ruby 1.7.3 (2002-09-02) [i586-linux]
   true

p((0.1 .. 2.0).member?(1.0))
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   true
=> -:1:in `member?': cannot iterate from Float (TypeError)
        from -:1
   ruby 1.7.3 (2002-09-02) [i586-linux]

p "b" < "ba"
p(("a"..."bc").max)
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   true
   "b"
=> ruby 1.7.3 (2002-09-05) [i586-linux]
   true
   "bc"

=> ruby 1.8.0 (2003-03-20) [i586-linux]
   true
   "b"

2002-06-01

win32ole.so [lib] [new]

新增

2002-05-30

Range#each [change]

Range#each 使用各元素的 succ 方法进行迭代操作。

(1.0 .. 2.0).each {|v| p v}
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   1
   2
=> -:1:in `each': cannot iterate from Float (TypeError)
        from -:1
   ruby 1.7.3 (2002-09-02) [i586-linux]

class Float
  def succ
   self + 1.0
  end
end
(1.0 .. 2.0).each {|v| p v}

=> ruby 1.7.3 (2002-09-02) [i586-linux]
   1.0
   2.0

2002-05-30

Range#size [obsolete]
Range#length [obsolete]

该方法也被删除。 [ruby-talk:64479], [ruby-talk:72133]

p(("a".."z").size)
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   26
=> -:1: undefined method `size' for #<Range:0x401aa780> (NoMethodError)
   ruby 1.7.2 (2002-08-01) [i586-linux]

若想得到Range的元素数量,必须这样

p(("a".."z").to_a.size)

=> ruby 1.7.2 (2002-08-01) [i586-linux]
   26

才行。

2002-05-29

Proc#binding [new]

新增

2002-05-28

负的数值字面值

2003-01-21: 该修改好像是变回原来的样子

对 -数值 的字面值的解释发生了变化,-数值 总是被当作一个字面值来处理。

例如,下面的表达式的结果就各不相同。

p -2**2
=> -:1: warning: ambiguous first argument; make sure
   ruby 1.6.7 (2002-03-01) [i586-linux]
   -4
=> -:1: warning: ambiguous first argument; make sure
   ruby 1.7.2 (2002-08-01) [i586-linux]
   4

=> -:1: warning: ambiguous first argument; make sure
   ruby 1.8.0 (2003-03-12) [i586-linux]
   -4

以前-2**2 被解释成-(2**2)。这是由于操作符的优先级不同所致 (真的如此吗?)。在1.7中则被解释成(-2)**2。另外,若在 - 和数值之间插入空格的话, - 会被当作单项操作符(方法)。(这与以前相同)

p(- 2**2)

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   -4
=> ruby 1.7.2 (2002-08-01) [i586-linux]
   -4

=> ruby 1.8.0 (2003-03-12) [i586-linux]
   -4

class Fixnum
  def -@
      1
  end
end

p(- 2**2)
=> -:2: warning: discarding old -@
   ruby 1.6.7 (2002-03-01) [i586-linux]
   1
=> -:2: warning: method redefined; discarding old -@
   ruby 1.7.2 (2002-08-01) [i586-linux]
   1

=> -:2: warning: method redefined; discarding old -@
   ruby 1.8.0 (2003-03-12) [i586-linux]
   1

2002-05-23

IO.sysopen [new]
Socket#sysaccept [new]
TCPServer#sysaccept [new]
UNIXServer#sysaccept [new]

新增

2002-05-13

[parser] [change]
String#to_f [change]
Float() [change]

在将字符串变为浮点数时,不再依赖库函数 strtod(3)了。这样,即使修改了库的内容,也不会影响到它的运作。

p "0xa.a".to_f

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   10.625
=> ruby 1.7.2 (2002-08-01) [i586-linux]
   0.0

2002-05-13

Float#to_s [compat]

表示最大精度的格式由"%.10g"变为"%.16g"。(2003-03-20: 其后又变为"%.15g" [ruby-bugs-ja:PR#406])

p 1.0/3
p 99.6
=> ruby 1.6.7 (2002-03-01) [i586-linux]
   0.3333333333
   99.6

=> ruby 1.7.2 (2002-08-01) [i586-linux]
   0.3333333333333333
   99.59999999999999

=> ruby 1.8.0 (2003-03-20) [i586-linux]
   0.333333333333333
   99.6

2002-05-10

Thread#join [compat]

可以使用limit来指定等待线程的时间。

2002-04-26

Enumerable#partition [new]

新增

2002-04-22

方法的参数中的 & [compat]
Proc#to_proc [new]

在使用 & 来修饰方法的参数时,若传给参数的对象中包含to_proc 方法就调用它,并把结果当作块来传给方法。以前,& 就只能修饰Proc, Method对象。另外,还新增了Proc#to_proc。

class Foo
  def to_proc
    p "should generate Proc object"
  end
end

def foo
end

foo(&Foo.new)

=> ruby 1.7.2 (2002-04-24) [i586-linux]
   "should generate Proc object"
   -:10: wrong argument type Foo (expected Proc) (TypeError)

2002-04-19

Numeric#step [compat]

Fixnum, Integer移动到这里。

2002-04-18

Regexp#to_s [new]

新增。[ruby-dev:16909]

p /foo(bar)*/.to_s
=> "(?-mix:foo(bar)*)"

2002-04-09

File.extname [new]

新增。返回文件名中的扩展名。[ruby-talk:37617]

2002-04-08

each_pair [new]

新增。

2002-04-06

Bignum [bug]

以前,若遇到比-2147483648还小的数值时,其2进制、8进制、16进制的表示形式就会出问题 [ruby-list:34828]

p "%b" % -2147483648
p "%b" % -2147483649
p "%b" % -2147483650

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   "..10000000000000000000000000000000"
   "..1"
   "..10"

=> ruby 1.7.2 (2002-04-11) [i586-linux]
   "..10000000000000000000000000000000"
   "..101111111111111111111111111111111"
   "..101111111111111111111111111111110"

2002-04-08

结束状态值 [compat]

raise SystemExit时,会使用结束状态值 1 。 [ruby-dev:16776]

2002-04-02

dl.so [lib] [new]

新增

2002-03-27

IO#sysseek(offset, whence) [new]

新增 [ruby-talk:21612], [ruby-talk:36703]

2002-03-26

net/http.rb [compat]

在Net::HTTP 的类方法中,可以使用URI对象了。

Net::HTTP.get_print(URI.parse('http://www.ruby-lang.org/ja/'))

请注意,在实例方法中则无法使用。

2002-03-26

rescue/ensure on begin .. end while [compat]

在包含rescue/ensure的begin语句中,也可以使用while/until来进行修饰了。

以前在包含rescue/ensure的while/until修饰表达式中,并没有最先执行主体部分(与C语言中的do ... while语法相同)。 [ruby-list:34618]

i = 0
begin
  p i
  i += 1
rescue
end while i < 0

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

=> ruby 1.7.2 (2002-03-29) [i586-linux]
   0

2002-03-26

rescue/ensure on class/module [compat]

不仅可以在方法定义中使用rescue/ensure,在类定义或模块定义中也可以如此。

class Foo
  hogehoge
rescue
  p $!
end

=> -:3: parse error
   ruby 1.6.7 (2002-03-01) [i586-linux]
=> ruby 1.7.2 (2002-03-29) [i586-linux]
   #<NameError: undefined local variable or method `hogehoge' for Foo:Class>

2002-03-25

Thread.list [compat]
ThreadGroup#list [compat]

已结束(aborting)的线程也被包含到列表中。 [rubyist:1282]

th = Thread.new {sleep}
Thread.critical = true
th.kill

p Thread.list

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   [#<Thread:0x401ba5c8 run>]

=> ruby 1.7.2 (2002-03-29) [i586-linux]
   [#<Thread:0x401b0618 aborting>, #<Thread:0x401ba0b4 run>]

2002-03-25

Thread#wakeup [bug]
Thread#run [bug]

若对已结束(aborting)的线程使用上述方法时,该线程就会起死回生。现在已经修复了这个bug。 [rubyist:1282]

2002-03-22

sprintf('%u') [compat]

在sprintf 的 '%u' 中,不再新增".."了。[ruby-dev:16522]

p sprintf("%u", -1)

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

=> -:1: warning: negative number for %u specifier
   ruby 1.7.2 (2002-03-29) [i586-linux]
   "4294967295"

2002-03-22

VMS support [platform]

打上了支持VMS的补丁。

附加库 [lib] [new]

新增了下列各库。 iconv.so, tsort.rb, stringio.so, strscan.so, fileutils.rb, racc/*

Dir.glob [compat]

可以指定Dir.glob的第2参数(决定匹配方式的标识)了。在Dir[] 中则无法使用该标识。

新增了相关的常数 File::FNM_DOTMATCH (表示 与FNM_PERIOD相反)。

p Dir.glob("/*")
=> ruby 1.7.2 (2002-03-15) [i586-linux]
   ["/lost+found", "/root", ...]

p Dir.glob("/*", File::FNM_DOTMATCH)

=> ruby 1.7.2 (2002-03-15) [i586-linux]
   ["/.", "/..", "/lost+found", "/root", "/boot", ...]
large file [bug]

可以正确处理large file(大小超过4G bytes的文件)了(真的?) [ruby-talk:35316], [ruby-talk:35470]

Process.kill [compat]

mswin32, mingw32中,也可以使用Process.kill(9, pid)来强制结束进程(TerminateProcess)。(好像Process.kill("KILL", pid)就不行???2002-08-28 以后好像可以使用 "KILL" 了)

benchmark.rb [new]

新增

abort [compat]

可以指定结束消息了。

abort("abort!")
=> abort!
   ruby 1.7.2 (2002-03-15) [i586-linux]

您所指定的消息会被设置给异常SystemExit对象的message 属性。

begin
  abort("abort!")
rescue SystemExit
  p $!.message
end

=> abort!
   ruby 1.7.2 (2002-03-29) [i586-linux]
   "abort!"
GDBM [lib] [change]
DBM [lib] [change]
SDBM [lib] [change]

文档中没有提到 [ruby-dev:16126]

Module#include [change]
Object#extend [change]

传递若干个模块时,include的顺序有所改变。好像[ruby-dev:16035] extend 也是如此。[ruby-dev:16183]

module Foo; end
module Bar; end
module Baz; end

include Foo, Bar, Baz
p Object.ancestors

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   [Object, Baz, Bar, Foo, Kernel]

=> ruby 1.7.2 (2002-03-01) [i586-linux]
   [Object, Foo, Bar, Baz, Kernel]

obj = Object.new
module Foo; end
module Bar; end
module Baz; end

obj.extend Foo, Bar, Baz
class << obj
  p ancestors
end

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   [Baz, Bar, Foo, Object, Kernel]

=> ruby 1.7.2 (2002-03-08) [i586-linux]
   [Foo, Bar, Baz, Object, Kernel]

这与一个一个地include时的顺序相反。

module Foo; end
module Bar; end
module Baz; end

include Foo
include Bar
include Baz
p Object.ancestors

=> ruby 1.7.2 (2002-03-01) [i586-linux]
   [Object, Baz, Bar, Foo, Kernel]
UNIXSocket.pair [new]
UNIXSocket.socketpair [new]
UNIXSocket#recv_io [new]
UNIXSocket#send_io [new]

新增

Proc#yield

[ruby-bugs-ja:PR#98] (2003-03-11: 该修改被取消 [ruby-dev:19799]) (其后Proc#yield也被取消)

Proc.new { break }.call
Proc.new { break }.yield

=> -:2:in `yield': break from proc-closure (LocalJumpError)
        from -:2
   ruby 1.7.3 (2002-09-05) [i586-linux]

=> ruby 1.8.0 (2003-03-12) [i586-linux]
Array#pack [compat]
String#unpack [compat]

可以在pack/unpack 的模板中写入注释了。

p [1,2,3,4].pack("s  # short (fixed 2 bytes)
                  i  # int (machine dependent)
                  l  # long (fixed 4 bytes)
                  q  # quad (fixed 8 bytes)")
=> ruby 1.7.2 (2002-02-21) [i586-linux]
   "\001\000\002\000\000\000\003\000\000\000\004\000\000\000\000\000\000\000"
LocalJumpError#exitstatus [new]

新增(其后变为exit_value)

def foo
  proc { return 10 }
end

begin
  foo.call
rescue LocalJumpError
  p $!.exitstatus
end

=> ruby 1.7.2 (2002-02-14) [i586-linux]
   10
UNIXServer#listen [new]
TCPServer#listen [new]

新增。与Socket#listen相同。

Time#getgm [new]
Time#getlocal [new]
Time#getutc [new]
Time#gmt_offset [new]
Time#gmtoff [new]
Time#utc_offset [new]

新增

2002-05-21

Module#<=> [change]

比较两个没有继承关系的类/模块时,将返回nil。

p Array <=> String

=> ruby 1.6.7 (2002-03-01) [i586-linux]
   1
=> ruby 1.7.3 (2002-09-13) [i586-linux]
   nil
IO#fsync [new]

新增

Array#pack [compat]
String#unpack [compat]

新征了64 bit 整数的模板字符 Q/q (表示Quad之意)。 Q表示unsigned,而q表示signed。 与perl不同的是,即使在不支持64 bit 整数的平台上,仍然可以使用。

p [ 1].pack("Q")
p [-1].pack("Q")
p [ 1].pack("q")
p [-1].pack("q")

p [ 1].pack("Q").unpack("Q")
p [-1].pack("Q").unpack("Q")
p [ 1].pack("q").unpack("q")
p [-1].pack("q").unpack("q")

=> ruby 1.7.2 (2002-02-13) [i586-linux]
   "\001\000\000\000\000\000\000\000"
   "\377\377\377\377\377\377\377\377"
   "\001\000\000\000\000\000\000\000"
   "\377\377\377\377\377\377\377\377"
   [1]
   [18446744073709551615]
   [1]
   [-1]
Method#inspect [compat]

特殊方法的输出形式更具实际意义了。 [ruby-bugs-ja:PR#193]

obj = []
def obj.foo
end
p obj.method(:foo)

=> ruby 1.6.6 (2001-12-26) [i586-linux]
   #<Method: Array(Array)#foo>

=> ruby 1.7.2 (2002-02-05) [i586-linux]
   #<Method: [].foo>

2002-01-28

Array.new [compat]
Array#fill [compat]

可以将块的计算结果指定为fill值。依次为各个元素计算块的内容,所以下列中每次都会生成"val"

ary = Array.new(3, "val")
p ary.collect {|v| v.id }       # => [537774036, 537774036, 537774036]
ary = Array.new(3) { "val" }
p ary.collect {|v| v.id }       # => [537770040, 537770028, 537770016]

2002-01-28

File::Stat#rdev_major [new]
File::Stat#rdev_minor [new]

新增

s = File.stat("/dev/null")
p s.rdev_major
p s.rdev_minor

=> ruby 1.7.2 (2002-01-28) [i686-linux]
   1
   3

2002-01-24

Hash#update [compat]

可以指定块了。还可以控制重复键的处理方式。

2002-01-18

IO.open [new]

新增

2002-01-14

Proc [bug]

当$SAFE为1或2时,被污染的Proc将无法变成块 [ruby-dev:15682]

$SAFE = 1
proc = proc {}
proc.taint
p proc.tainted?
def foo(&b)
  p b.tainted?
end
foo(&proc)

=> ruby 1.6.8 (2003-08-03) [i586-linux]
   true
   true
=> ruby 1.7.2 (2002-01-23) [i586-linux]
   true
   true

2002-01-08

String#to_i [compat]

可以将基数(2,8,10,16)指定给参数。(2002-01-26: 当参数为0时,用prefix来判定基数)

p "010".to_i(16)
=> ruby 1.7.2 (2002-01-11) [i586-linux]
   16

2001-12-08

Hash.new [compat]

可以把块当作哈希的默认值了。指定块之后,每次使用空的哈希元素时都会执行块的内容,并返回其结果。此时会把 哈希本身 和 使用哈希时的键 传给块。

h = Hash.new("foo")
p h.default.id
p h.default(0).id    # Hash#default 可以指定传给块的键
p h[0].id
p h[0].id
p h[1].id

=> ruby 1.7.2 (2001-12-10) [i586-linux]
   537774276
   537774276
   537774276
   537774276

h = Hash.new { "foo" }
p h.default.id
p h.default(0).id
p h[0].id
p h[0].id
p h[1].id

=> ruby 1.7.2 (2001-12-10) [i586-linux]
   537770616
   537770352
   537770316
   537770280

h = Hash.new { raise IndexError, "undefined!!" }
p h[0]

=> -:1: undefined!! (IndexError)
        from -:1:in `yield'
        from -:2:in `default'
        from -:2:in `[]'
        from -:2
   ruby 1.7.2 (2001-12-10) [i586-linux]

2001-12-11

Array#select
Hash#select
ENV.select
MatchData#select
Struct::XXX#select

新增(此后被values_at方法所取代)

# 没有给出块的话,则与indexes/indicies 相同。
# (注: indexes/indicies已变为obsolete)

p [1,2,3].select(0,1,2,3)
p [1,2,3].select(-4,-3,-2,-1)

p( {1=>"a", 2=>"b", 3=>"c"}.select(3,2,1) )


=> ruby 1.7.2 (2001-12-10) [i586-linux]
   [1, 2, 3, nil]
   [nil, 1, 2, 3]
   ["c", "b", "a"]

# 若给出了块的话,则与Enumerable#select 相同。

p [1,2,3,4,5].select {|v| v % 2 == 1}
p( {1=>"a", 2=>"b", 3=>"c"}.select {|k,v| k % 2 == 1} )

=> ruby 1.6.6 (2001-12-04) [i586-linux]
   [1, 3, 5]
   [[1, "a"], [3, "c"]]

=> ruby 1.7.2 (2001-12-10) [i586-linux]
   [1, 3, 5]
   [[1, "a"], [3, "c"]]

m = /(foo)(bar)(baz)/.match("foobarbaz")
p m.select(0,1,2,3,4)   # same as m.to_a.indexes(...)
p m.select(-1,-2,-3)

=> ruby 1.7.2 (2001-12-10) [i586-linux]
   ["foobarbaz", "foo", "bar", "baz", nil]
   ["baz", "bar", "foo"]

2001-12-11

String#match(re) [new]

新增。与 re.match(str) 相同。

2001-11-17

Marshal [marshal] [change]

对Float进行dump时,不再依赖sprintf(3)了。format version由4.6升到4.7。 (此后,由于把strtod(3)收入了语言本身,即使进行读入时也不再依赖strtod(3)了)

2001-11-12

trap [bug]
trace_var [bug]

如将受污染的字符串传给第二参数的话,就会引发SecurityError异常。在1.6中,若安全级别为4则会计算受污染的字符串。 [ruby-list:32215]

2001-10-16

Module.new [compat]
Class.new [compat]

在Module.new, Class.new中,若给出了块的话,则在生成的模块/类的上下文中计算块的内容。

Module.new {|m| p m}

=> ruby 1.7.1 (2001-10-15) [i586-linux]
   #<Module:0x401afd5c>

2001-10-10

Object#clone [change]

不能对Numeric这种immutable对象进行clone。 [ruby-bugs-ja:PR#94], [rubyist:0831]

$DEBUG=true
true.clone     rescue nil
false.clone    rescue nil
nil.clone      rescue nil
:sym.clone     rescue nil
(10**10).clone rescue nil
0.clone        rescue nil

=> Exception `TypeError' at -:2 - can't clone true
   Exception `TypeError' at -:3 - can't clone false
   Exception `TypeError' at -:4 - can't clone nil
   Exception `TypeError' at -:5 - can't clone Symbol
   ruby 1.6.6 (2001-12-26) [i586-linux]

=> Exception `TypeError' at -:2 - can't clone TrueClass
   Exception `TypeError' at -:3 - can't clone FalseClass
   Exception `TypeError' at -:4 - can't clone NilClass
   Exception `TypeError' at -:5 - can't clone Symbol
   Exception `TypeError' at -:6 - can't clone Bignum
   Exception `TypeError' at -:7 - can't clone Fixnum
   ruby 1.7.1 (2001-10-10) [i586-linux]
puts
Array#to_s

puts不再对数组进行特殊处理了,而是输出Array#to_sArray#to_s在默认情况下会输出带换行的字符串,所以从其输出形式看来是没有什么变化的(但要受到$,的值的影响)。[ruby-dev:15043]

该修改尚处于试验阶段,又可能会改回原样。。。[ruby-dev:15313]

$, = ","
puts %w(foo bar baz)
=> ruby 1.6.5 (2001-11-01) [i586-linux]
   foo
   bar
   baz
=> ruby 1.7.2 (2001-11-25) [i586-linux]
   foo,bar,baz

???好像是改回原样了。

=> ruby 1.7.2 (2001-12-10) [i586-linux]
   foo
   bar
   baz
Integer#to_s [compat]

可以将基数指定给参数了。

p 10.to_s(16)
=> ruby 1.7.2 (2001-11-25) [i586-linux]
   "a"
String#chomp [change]
String#chomp! [change]
chomp [change]
chomp! [change]

只要$/ 的值为"\n" (默认),不管是哪种行尾("\r\n", "\r"或"\n")都可以清除干净。

p "aaa\r\n".chomp
=> ruby 1.6.5 (2001-11-01) [i586-linux]
   "aaa\r"
=> ruby 1.7.2 (2001-11-25) [i586-linux]
   "aaa"
Complex#to_i [lib] [obsolete]
Complex#to_f [lib] [obsolete]
Complex#to_r [lib] [obsolete]

Complex#to_i, #to_f, #to_r已被取消。 [ruby-bugs-ja:PR#102], [rubyist:0879]

方法调用 [parser] [change]

若方法名和括弧之间有空格,则该括号不会为当作是包含参数的括号,而会被当作表达式中的括号。

p (1+2)*3

=> -:1: warning: p (...) interpreted as method call
   -:1: warning: useless use of * in void context
   ruby 1.6.5 (2001-09-19) [i586-linux]
   3
   -:1: undefined method `*' for nil (NameError)

=> -:1: warning: p (...) interpreted as command call
   ruby 1.7.1 (2001-06-05) [i586-linux]
   9
Marshal [marshal] [bug]

若对结构体类的子类进行dump的话,则无法读出。[ruby-bugs-ja:PR#104]

S = Struct.new("S", :a)
class C < S
end
p Marshal.load(Marshal.dump(C.new))

=> -:4: warning: instance variable __member__ not initialized
   -:4:in `dump': uninitialized struct (TypeError)
        from -:4
   ruby 1.6.5 (2001-09-19) [i586-linux]

=> ruby 1.7.1 (2001-10-19) [i586-linux]
   #<C a=nil>
alias [bug]

全局变量的别名无效。 [ruby-dev:14922]

$g2 = 1
alias $g1 $g2
p [$g1, $g2]
$g2 = 2
p [$g1, $g2]
=> ruby 1.6.5 (2001-09-19) [i586-linux]
   [1, 1]
   [1, 2]

=> ruby 1.7.1 (2001-10-19) [i586-linux]
   [1, 1]
   [2, 2]

2001-10-03

String#[] [new]
String#[]= [new]

新增

String#[re, idx]
String#[re, idx] = val

新增第二个可选参数idx。

p "foobarbaz"[/(foo)(bar)(baz)/, 1]
p /(foo)(bar)(baz)/.match("foobarbaz").to_a[1]
=> -:2: warning: ambiguous first argument; make sure
   ruby 1.7.1 (2001-10-05) [i586-linux]
   "foo"
   "foo"

str = "foobarbaz"
p str[/(foo)(bar)(baz)/, 2] = "BAR"  # => "BAR"
p str                                # => "fooBARbaz"

str[/re/, 0] 与 str[/re/] 相同。

2001-10-02

Class#allocate [new]

由allocate 和 initialize 这两个方法来生成对象。[ruby-dev:14847] 请参考 rb_define_alloc_func() 。

2001-09-24

Array.new [compat]

若将数组传给Array.new 的参数时,将会生成该数组的拷贝。

ary = [1,2,3]
ary2 = Array.new ary
p ary, ary2
p ary.id, ary2.id

=> ruby 1.7.1 (2001-10-05) [i586-linux]
   [1, 2, 3]
   [1, 2, 3]
   537758120
   537755360

2001-09-18

String.new [compat]

可以省略String.new 的参数了。

p String.new
=> -:1:in `initialize': wrong # of arguments(0 for 1) (ArgumentError)
        from -:1:in `new'
        from -:1
   ruby 1.7.1 (2001-08-29) [i586-linux]

=> ruby 1.7.1 (2001-10-05) [i586-linux]
   ""

2001-09-11

Dir#path [new]

新增

p Dir.open(".").path
=> ruby 1.7.1 (2001-10-05) [i586-linux]
   "."

2001-08-26

Readline [change]

在Readline.readline的执行过程中使用Ctrl-C进行中断之后,还可以恢复终端状态。[ruby-dev:14574]

2001-08-29

Precision.included [new]

新增(Module#included的重定义)

2001-08-23

Signal 模块 [new]

新增。

while, until, class, def 的值 [ruby] [change]

while, until, class, def能返回值了。

class/module 返回最后计算的表达式的值。def返回nil。while/until通常返回 nil,若使用带参数的break的话,则可以返回任何值。

p(while false; p nil end)
p(while true; break "bar" end)
p(class Foo; true end)
p(module Bar; true end)
p(def foo; true end)
=> -:1: void value expression
   -:2: void value expression
   -:3: void value expression
   -:4: void value expression
   -:5: void value expression
   ruby 1.7.1 (2001-08-20) [i586-linux]
=> -:1: warning: void value expression
   -:2: warning: void value expression
   -:3: warning: void value expression
   -:4: warning: void value expression
   -:5: warning: void value expression
   ruby 1.7.1 (2001-08-23) [i586-linux]
   false
   "bar"
   true
   true
   nil

修正后,while/until会在途中返回nil。 [ruby-dev:15909]

=> -:1: warning: void value expression
   -:2: warning: void value expression
   -:3: warning: void value expression
   -:4: warning: void value expression
   -:5: warning: void value expression
   ruby 1.7.2 (2002-02-20) [i586-linux]
   nil
   "bar"
   true
   true
   nil
Range#===

以前在对 字符串的范围对象 和 字符串 进行比较时,只会与范围的两段作比较。而现在则使用String#upto来和每个元素进行比较。

(2002-06-04: 之后作的修改)

p(("a" .. "ab") === "aa")
=> ruby 1.7.1 (2001-08-20) [i586-linux]
   true
=> ruby 1.7.1 (2001-08-23) [i586-linux]
   false
Enumerable#sort_by [new]

新增。这是为处理[ruby-dev:8986]之后提到的Schwartzian transform而准备的sort。

Curses [lib] [compat]

Updated. New methods and constants for using the mouse, character attributes, colors and key codes have been added.

Range#step([step=1]) [new]

新增。每隔step就使用对应元素进行迭代。

条件式中的正则表达式字面值 [parser] [change]

条件式中的正则表达式字面值 会给出警告。

在于$_ 进行正则表达式匹配时,推荐您这样显式地处理 ~/re/ (单项的 ~方法)。

$_ = "foo"
p $_ if /foo/
p $_ if /bar/

=> -:2: warning: regex literal in condition
   -:3: warning: regex literal in condition
   ruby 1.7.1 (2001-08-14) [i586-linux]
   "foo"
String#lstrip [new]
String#rstrip [new]
String#lstrip! [new]
String#rstrip! [new]

新增。去除左端或右端的空格。

Socket.pack_sockaddr_in [new]
Socket.unpack_sockaddr_in [new]

新增。套接字地址结构体(INET domain)的pack/unpack。

Socket.pack_sockaddr_un [new]
Socket.unpack_sockaddr_un [new]

新增。套接字地址结构体(UNIX domain)的pack/unpack。

String#casecmp [new]

新增。忽略字母的大小写区别来比较字符串。

String#eql? [change]

不管$=的值如何,总是区分字母的大小写。

Module#include? [new]

新增 [ruby-dev:13941]

Dir.chdir [bug]

Changed to warn only when invoked from multiple threads or no block is given. [ruby-dev:13823]

Dir.chdir("/tmp")

pwd = Dir.pwd       #=> "/tmp"
puts pwd

Dir.chdir("foo") {
  pwd = Dir.pwd     #=> "/tmp/foo"
  puts pwd

  Dir.chdir("bar") {        # <-- previously warned
    pwd = Dir.pwd   #=> "/tmp/foo/bar"
    puts pwd
  }

  pwd = Dir.pwd     #=> "/tmp/foo"
  puts pwd
}

pwd = Dir.pwd       #=> "/tmp"
puts pwd
Proc#yield

新增 [ruby-dev:13597] (之后又被删除了)

除去它不检查参数的个数之外,其他则与Proc#call 相同。

File.fnmatch [new]
File.fnmatch? [new]

新增

File::Constants模块中定义了该方法所用的FNM_NOESCAPE, FNM_PATHNAME, FNM_PERIOD, FNM_CASEFOLD标识。

p %w(foo bar bar.bak).reject! { |fn| File::fnmatch?("*.bak", fn) }
=> ruby 1.7.1 (2001-06-12) [i586-linux]
   ["foo", "bar"]

2001-06-12

Method#== [new]

新增

2001-06-12(?)

多重赋值 [change]

修改了多重赋值的规则。变更如下。

#
*a = nil
p a
=> ruby 1.7.1 (2001-06-05) [i586-linux]
   [nil]
=> ruby 1.7.1 (2001-06-12) [i586-linux]
   []
=> ruby 1.8.0 (2003-01-18) [i586-linux]
   [nil]

但好像是又改回去了。与2003-01-07 的 eval.c的块参数比较起来,它应该是正确的。

def foo
  yield nil
  yield
end
foo {|*a| p a}

=> ruby 1.6.8 (2002-12-24) [i586-linux]
   [nil]
   [nil]
=> ruby 1.8.0 (2003-08-04) [i586-linux]
   [nil]
   []

2001-06-05(?)

展开数组 [change]

修正了下列问题。现在,只包含1元素的数组也能被正常展开。

a = *[1]
p a #=> [1]

=> ruby 1.6.8 (2002-12-24) [i586-linux]
   [1]
=> ruby 1.7.1 (2001-06-05) [i586-linux]
   1
NameError & NoMethodError [change]

重新回到NameError を StandardError 的子类中去。类的层次关系如下。

NoMethodError < NameError < StandardError.
File.open [bug]

以前,只有将第2参数指定为数值(File::RDONLY|File::CREAT等)时,才会使用第3参数。现在只要给出了第3参数,就总是有效的。[ruby-bugs-ja:PR#54]

[ruby] [compat]

由于使用了内部的哈希表,所以使用常数的速度有所提升。(对应于ChangeLog的

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

部分)

语法 [parser] [change]

下列代码(请注意p后面的空格)

p ("xx"*2).to_i

不会被解生成

(p("xx"*2)).to_i

而是

p (("xx"*2).to_i)

这样(这只是试验性的修改)。

Range#to_ary

新增。现在(因为会自动进行数组变换,所以)可以写成这样。(2003-03-29: 此后Range#to_ary就被删除了)

a, b, c = 1..3
p [a, b, c]

=> ruby 1.6.8 (2002-12-24) [i586-linux]
   [1..3, nil, nil]

=> ruby 1.7.3 (2002-12-11) [i586-linux]
   [1, 2, 3]

=> ruby 1.8.0 (2003-03-29) [i586-linux]
   [1..3, nil, nil]
break and next [compat]

使用参数之后,break, next就可以返回 迭代器 或 yield 的值了。(该功能尚处于试验阶段)

break [n]会终止迭代器,n就是迭代器的返回值。 而next [n]会跳到块的外面,n就是yield的返回值。

def foo
  p yield
end

foo { next 1 }

def bar
  yield
end

p bar { break "foo" }

=> ruby 1.7.1 (2001-08-20) [i586-linux]
   1
   "foo"
to_str [compat]

定义了to_str的对象将在更大的空间内扮演String的角色。

大部分将字符串作为参数的内部方法都在尝试调用to_str进行隐式的类型变换。

foo = Object.new
class <<foo
  def to_str
    "foo"
  end
end
p File.open(foo)
=> -:7:in `open': wrong argument type Object (expected String) (TypeError)
   ruby 1.6.4 (2001-04-19) [i586-linux]
=> -:7:in `open': No such file or directory - "foo" (Errno::ENOENT)
   ruby 1.7.0 (2001-05-02) [i586-linux]
扩展库API(STR2CSTR()) [api] [new]

如果把一个包含to_str方法的非字符串对象传给扩展库的API--STR2CSTR()的话,它就会在内部调用to_str,进行隐式的类型转换。此时虽然能返回变换结果所保持的字符串指针,但在该API中,这个隐式变换的结果不会被任何对象所使用,因此可能会被GC回收掉。 [ruby-dev:12731]

version 1.7以后,使用StringValuePtr()来替代它。此时,参数所用的对象会被隐式转换结果所替代,因此变换结果不会被GC所回收。(在version 1.7中,STR2CSTR()变成obsolete)

另外还准备了一个新的API--StringValue()。在需要对参数进行to_str的隐式类型变换时使用它。若参数是字符串的话,则不进行任何操作。把它用在处理字符串的方法的前面则会相当方便。

目前还没有开发出替代str2cstr() (返回C指针和字符串长度)的安全的API。(在[ruby-dev:15644]中有一些建议)

范围操作符表达式中的字面值 [ruby] [change]

只有在使用-e选项的单行脚本中,才能对 范围操作符表达式中的单个数值字面值 和 $. 进行比较。

rescue中的异常类 和 发生的异常对象 之间的比较 [ruby] [change]

使用Module#===来比较 发生的异常$! 和 rescue中的异常类。

以前使用kind_of?来进行比较时,基本上也没有什么问题。这里主要是对SystemCallError.===进行了重定义,只要两个异常的errno相同就把它们看作是同一个异常。因此,若Errno::EWOULDBLOCK 和 Errno::EAGAIN的意义相同(相同的errno)时,不管指定哪个,都可以进行rescue。

后来,只要两个Errno::XXX对象的errno相同,就被看作是相同的异常,因此这个修改也就失效了,但却一直保留下来。 (或许在用户定义异常类时还能用到) [ruby-dev:19589]

Array#collect [bug]
Array#map [bug]

在不带块的时候,Array#collect会返回self.dup。因此可能会返回Array以外的对象[ruby-list:30480]

Foo = Class.new Array

a = Foo.new
p a.map.class
p a.collect.class

=> ruby 1.7.1 (2001-06-12) [i586-linux]
   Array
   Foo

=> ruby 1.7.1 (2001-07-31) [i586-linux]
   Array
   Array
Array#dup

修正了dup中的bug [ruby-list:30481] (1.6 中也进行了修正)

class Foo < Array
  attr_accessor :foo
end

a = Foo.new
a.foo = 1
b = a.dup
b.foo
b.foo = 99
p b.foo

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

# => ruby 1.6.4 (2001-07-31) [i586-linux]
     99
Array#fetch [new]

新增

Array#insert [new]

新增 [ruby-talk:14289]

ary[n,0] = [other,...] 相同(但却返回self)

ary = [0,1,2,3]
ary[2, 0] = [4, 5, 6]
p ary

ary = [0,1,2,3]
ary.insert(2, 4, 5, 6)
p ary
Array#pack [change]
String#unpack [change]

Array#pack, String#unpack 的模板字符"p", "P"可以对nil和NULL指针进行互换了。[ruby-dev:13017]

p [nil].pack("p")
p "\0\0\0\0".unpack("p")

=> ruby 1.7.0 (2001-05-17) [i586-linux]
   "\000\000\000\000"
   [nil]
Array#sort! [change]

总是返回self。

不能保证将来一直如此 [ruby-dev:12506]

Class.inherited [compat]

(注: 并非Class#inherited)

以前为了禁止类定义子类而设立该方法,(其作用是引发TypeError异常)现在由Class.new来完成这个任务,所以Class.inherited方法就被删除了。

class SubClass < Class
end

#=> -:1:in `inherited': can't make subclass of Class (TypeError)
            from -:1
    ruby 1.7.1 (2001-06-12) [i586-linux]

#=> -:1: can't make subclass of Class (TypeError)
    ruby 1.7.1 (2001-07-31) [i586-linux]
Dir.open [change]

若带块的话,则与File.open相同,块的结果成为方法的返回值。(在1.6以前,其返回值恒为nil)

Dir.chdir [compat]

可以指定块了。

Dir.glob [change]

可以使用前面的反斜线来对通配符进行转义处理。另外,空格也不再具有特殊意义('\0'依然有效)。

Enumerable#all? [new]
Enumerable#any? [new]
Enumerable#inject [new]

新增

File.lchmod [new]
File.lchown [new]

新增

IO.for_fd [new]

新增

IO.read [new]

新增。主要是实现了[ruby-talk:9460]中提到的功能

Interrupt [change]

Interrupt 成为SignalException的子类。(在1.6以前,它是Exception的子类)

Marshal::MAJOR_VERSION [new]
Marshal::MINOR_VERSION [new]

新增。Marshal输出的dump format的版本号。 [ruby-dev:14172]

MatchData#to_ary

新增 [ruby-dev:12766] (2003-03-28: 后来又消失了)

为了方便Regexp#match而设。以前必须得

foo, bar, baz = /(\w+?)\s+(\w+?)\s+(\w+)/.match("foo bar baz").to_a[1..-1]
p [foo, bar, baz]

这样才行。现在可以

_, foo, bar, baz = /(\w+?)\s+(\w+?)\s+(\w+)/.match("foo bar baz")
p [foo, bar, baz]

这样。

Math.acos [new]
Math.asin [new]
Math.atan [new]
Math.cosh [new]
Math.sinh [new]
Math.tanh [new]
Math.hypot [new]

新增

Module#included [new]

新增。在Module#append_feature后调用的hook

Module#method_removed [new]
Module#method_undefined [new]

新增

Numeric#/

新增。返回商。

(之后变成div(?))

NoMethodError [new]

新增 [ruby-dev:12763]

NotImplementError [obsolete]

旧称被删除。请使用NotImplementedError

Object#singleton_method_removed [new]
Object#singleton_method_undefined [new]

新增

Object#singleton_methods [compat]

新增了可选参数all。

class Foo
  def foo
  end
end
obj = Foo.new

module Bar
  def bar
  end
end

class <<obj
  include Bar
  def baz
  end
end
p obj.singleton_methods      #=> ["baz"]
p obj.singleton_methods true #=> ["baz", "bar"]
Process.times [change]

Time.times移到这里。(Time.times还在,但会出现warning)

Process::Status [new]

新增。$? 的值从整数中分离出来,变成该类的实例。

Process.waitall [new]

新增

Range#include? [new]
Range#member? [new]

新增

Regexp.last_match [compat]

新增了可选参数。

Regexp#options [new]

新增

String#casecmp [new]

新增。比较字符串而不区分大小写。

String#insert [new]

新增

str[n, 0] = other 相同(但会返回 self)

Symbol.all_symbols [new]

新增 [ruby-dev:12921]

Symbol#intern

新增(???之后又被删除)

SystemCallError.=== [new]

新增 (请参考上面的「rescue 节的...」内容) [ruby-dev:12670]

SystemExit#status [new]

新增

TCPSocket.new [compat]
TCPSocket.open [compat]

可使用第3,4参数来进行指定。

Thread#keys [new]

新增。返回Thread固有数据的键的数组。

Time [compat]

可以处理负的 time_t (仅限于OS支持的场合)

p Time.at(-1)
=> Thu Jan 01 08:59:59 JST 1970
Time#to_a [change]
Time#zone [change]

对gmtime 时区返回UTC" (以前取决于系统环境,大部分场合返回"GMT")