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]
       #<MatchData:0x401b1be4>
       -:3: wrong argument type nil (expected Match) (TypeError)
                                              ^^^^^ MatchData的错误
    => ruby 1.6.7 (2002-04-04) [i586-linux]
       #<MatchData:0x401b1c98>
       nil

2002-03-25 BasicSocket.do_not_reverse_lookup

    在$SAFE > 3的情况下,无法设定值。[ruby-dev:16554]
2002-03-23 IO#read

    修复了File#read等无法读取大小为0的有内容文件(在Linux的/proc文件系统中会发生这种情况)的bug。

    p File.open("/proc/#$$/cmdline").read

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

    => ruby 1.6.7 (2002-03-29) [i586-linux]
       "ruby-1.6\000-v\000-"

2002-03-22 module_eval

    在module_eval的块中,常数和类变量的作用域不再变化。[ruby-dev:17876]

    class Foo
      FOO = 1
      @@foo = 1
    end

    FOO = 2
    @@foo = 2

    Foo.module_eval { p FOO, @@foo }

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

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

2002-03-22 net/http.rb

    以前,Net::HTTP.new在不带块的时候返回nil。 [ruby-bugs-ja:PR#214]

    一般认为会逐渐取消net/protocol.rb,该bug好像是在调试时不小心种下的。
2002-03-20 File.expand_path

    有时会出现内存释放不彻底的情况。[ruby-bugs:PR#276]
2002-03-18 字符串字面值

    在#{..}等结构中,有时会出现汉字代码处理不全的现象。[ruby-list:34478]

    #! ruby -Ks
    p a = "#{"表"}"
    => -:1: compile error in string expansion (SyntaxError)
       -:1: unterminated string meets end of file
       ruby 1.6.7 (2002-03-15) [i586-linux]
    => ruby 1.6.7 (2002-03-19) [i586-linux]
       "表"

    #! ruby -Ks
    p %[评价]
    => -:2: parse error
               p %[评价]
                       ^
       ruby 1.6.7 (2002-03-15) [i586-linux]

    => ruby 1.6.7 (2002-03-19) [i586-linux]
       "评价"

2002-03-16 $~

    以前,若正则表达式方法没有在内部进行匹配操作时,将不会清除$~ 的状态。[ruby-bugs-ja:PR#208]

    /foo/ =~ "foo"
    /foo/ =~ nil
    p $~

    /foo/ =~ "foo"
    $_ = nil; ~"foo"
    p $~

    /foo/ =~ "foo"
    "foo".index(/bar/, 4)
    p $~

    /foo/ =~ "foo"
    "foo".rindex(/bar/, -4)
    p $~

    => ruby 1.6.7 (2002-03-06) [i586-linux]
       #<MatchData:0x401b1be4>
       #<MatchData:0x401b198c>
       #<MatchData:0x401b1644>
       #<MatchData:0x401b1414>
    => ruby 1.6.7 (2002-03-19) [i586-linux]
       nil
       nil
       nil
       nil

2002-03-14 扩展库的autoload

    无法对扩展库进行autoload。[ruby-dev:16379]

    autoload :Fcntl, "fcntl"
    require "fcntl"

    => -:2:in `require': uninitialized constant Fcntl (NameError)
            from -:2
       ruby 1.6.7 (2002-03-01) [i586-linux]

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

2002-03-13 getopts.rb

    refine. [ruby-dev:16193], [ruby-dev:16213]
2002-03-11 正则表达式中的8进制代码

    以前,在正则表达式中的\nnn形式的8进制表示法中,只有开头是0时,才允许4位数。[ruby-bugs-ja:PR#207]

    p /\0001/ =~ "\0001"   # equivalent to "\0" + "1"
    => -:1: warning: ambiguous first argument; make sure
       ruby 1.6.7 (2002-03-01) [i586-linux]
       nil
    => -:1: warning: ambiguous first argument; make sure
       ruby 1.6.7 (2002-03-15) [i586-linux]
       0

2002-03-11 trap

    [ruby-bugs-ja:PR#206]

    trap('EXIT','Foo')
    => -:1: [BUG] Segmentation fault
       ruby 1.6.7 (2002-03-01) [i586-linux]
    => ruby 1.6.7 (2002-03-15) [i586-linux]

2002-03-10 方法的返回值

    下列方法的返回值已被修正。[ruby-bugs-ja:PR#205]

        * 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 #<Proc:0x401b1b30> (NameError)
            from -:1
       ruby 1.6.7 (2002-03-01) [i586-linux]

    => ruby 1.6.6 (2001-12-26) [i586-linux]
       "foo"

1.6.6 (2001-12-26) -> 1.6.7 (2002-03-01)

2002-02-20 true/false/nil的特殊方法定义

    可以通过定义特殊类的方法来为这些伪变量定义特殊方法。

    class <<true
      def foo
       "foo"
      end
    end
    p true.foo
    => -:1: no virtual class for true (TypeError)
       ruby 1.6.6 (2001-12-26) [i586-linux]

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

time.rb, URI

    已添加。
Ruby/Tk

    修复bug,增加功能[ruby-dev:16139],[ruby-dev:16153]。
数值字面值的`_'

    重新制定`_'的使用规则,统一了String#hex等数值变换方法的行为规则。[rubyist:1018], [ruby-dev:15684], [ruby-dev:15757]
include

    不会递归地对模块进行include操作。

    module Foo; end
    module Bar; include Foo; end
    module Foo; include Bar; end

    p Foo.ancestors

    => ruby 1.6.6 (2001-12-26) [i586-linux]
       [Foo, Bar, Foo]

    => -:3:in `append_features': cyclic include detected (ArgumentError)
            from -:3:in `include'
            from -:3
       ruby 1.6.6 (2002-01-28) [i586-linux]

方法的返回值

    修正了下列方法的返回值。 [ruby-bugs-ja:PR#182], [rubyist:1016]

        * Hash#default= 返回右边部分(以前返回self)。
        * Dir#pos= 返回右边部分(以前返回self)。 (Dir#seek仍然返回self)
        * Dir.glob 带块时返回nil(以前返回false)
        * IO#close 遇到已关闭的IO则引发IOError。
        * IO#each_byte 返回self(以前返回nil)

rb_define_module_under()

    以前,若C函数 rb_define_module_under()定义模块时遇到了已定义的同名常数的话就会失败。[ruby-talk:30203]

    Constants = 1
    require 'syslog'
    p Syslog::Constants

    => -:2:in `require': Syslog::Fixnum is not a module (TypeError)
            from -:2
       ruby 1.6.6 (2001-12-26) [i586-linux]

    => ruby 1.6.6 (2002-01-07) [i586-linux]
       Syslog::Constants

    因为这个bug的问题,可能最近就会放出1.6.7[ruby-talk:30387](好像不是这样。因此使用1.6.6的stable-snapshot的用户需要特别注意。因为2002/1/30的下列变更(ChangeLog)

        * re.c (rb_reg_search): should set regs.allocated.

    的原因,将导致内存不足。2002/2/13以后的修正版解决了这个问题)。

1.6.5 (2001-09-19) -> 1.6.6 (2001-09-19)

Syslog

    已添加。
CGI

    针对Netscape(版本是?)的bug进行了处理 [ruby-list:32089]
Time#localtime
Time#gmtime

    可以调用一次已冻结的Time 对象。

    t = Time.new.freeze
    p t.gmtime
    p t.localtime

    => -:2:in `gmtime': can't modify frozen Time (TypeError)
            from -:2
       ruby 1.6.5 (2001-09-19) [i586-linux]

    => ruby 1.6.5 (2001-11-01) [i586-linux]
       Mon Nov 05 18:08:34 UTC 2001
       -:3:in `localtime': can't modify frozen Time (TypeError)
            from -:3

File::SEPARATOR
File::ALT_SEPARATOR
File::PATH_SEPARATOR
RUBY_PLATFORM
RUBY_RELEASE_DATE
RUBY_VERSION

    上述各项已变为被freeze的字符串。

    p File::SEPARATOR.frozen?
    p File::ALT_SEPARATOR.frozen?
    p File::PATH_SEPARATOR.frozen?

    => ruby 1.6.5 (2001-09-19) [i586-linux]
       false
       false
       false

    => ruby 1.6.5 (2001-11-01) [i586-linux]
       true
       false  # 因为运行环境是Linux,所以ALT_SEPARATOR是nil
       true

Integer[nth]

    以前,若遇到大索引值就会引发异常。 [ruby-bugs-ja:PR#114]

    p(-1[10000000000])

    => -:1:in `[]': bignum too big to convert into `int' (RangeError)
            from -:1
       ruby 1.6.5 (2001-09-19) [i586-linux]

    => ruby 1.6.5 (2001-11-01) [i586-linux]
       1

    不能对整数的负索引返回0。?[ruby-bugs-ja:PR#122]

    p(-1[-1])

    => ruby 1.6.5 (2001-09-19) [i586-linux]
       1
    => ruby 1.6.5 (2001-11-01) [i586-linux]
       1

Numeric#remainder

    [ruby-bugs-ja:PR#110]

    p( 3.remainder(-3))
    p(-3.remainder(3))

    => ruby 1.6.5 (2001-09-19) [i586-linux]
       3
       -3
    => ruby 1.6.5 (2001-11-01) [i586-linux]
       0
       0

END { ... }

    以前,不能运行END块中的END块。 [ruby-bugs-ja:PR#107]

    END {
      p 1
      END { p 2 }
    }

    => ruby 1.6.5 (2001-09-19) [i586-linux]
       1

    => ruby 1.6.5 (2001-11-01) [i586-linux]
       1
       2

String#succ

[ruby-talk:22557]

p "***".succ
p "*".succ
p sprintf("%c", 255).succ
p sprintf("*%c", 255).succ
p sprintf("**%c", 255).succ

=> ruby 1.6.5 (2001-09-19) [i586-linux]
   "**+"
   "\001+"
   "\001\000"
   "\001+\000"
   "*+\000"

=> ruby 1.6.5 (2001-11-01) [i586-linux]
   "**+"
   "+"
   "\001\000"
   "+\000"
   "*+\000"

method_missing

    以前,下列内容被Segmentation Fault。[ruby-dev:14942]

    Module::constants.each {|c|
      c = eval c
      if c.instance_of?(Class)
        p c
        c.instance_methods.each {|m|
          c.module_eval "undef #{m};"
        }
        c.module_eval {undef initialize}
      end
    }

    => ruby 1.6.5 (2001-09-19) [i586-linux]
       NotImplementedError
       MatchData
       Exception
       Numeric
       MatchData
       Segmentation fault

    => ruby 1.6.5 (2001-10-15) [i586-linux]
       MatchData
       NotImplementedError
       FloatDomainError
       LoadError
       Float
       Binding
       SignalException
       Module
       -:6:in `method_missing': stack level too deep (SystemStackError)

%q(...)

    在使用%表示法的字面值中,不能将英文字母和数字用作切分字符。

    p %q1..1

    => ruby 1.6.5 (2001-10-10) [i586-linux]
       ".."
    => -:1: unknown type of %string
            p %q1..1
                 ^
       ruby 1.6.5 (2001-10-15) [i586-linux]

String#=~

    调用String#=~时,若两边都是字面值的话,为了提升速度而禁止进行方法调用。(实际上,此前就曾考虑过这么做,但因为出现了bug而未能禁止方法调用(不是String#=~,而是Regexp#=~))

    class String
      def =~(arg)
        ["String#=~", self, arg]
      end
    end

    class Regexp
      def =~(arg)
        ["Regexp#=~", self, arg]
      end
    end

    p "foo" =~ /foo/
    p "foo" =~ Regexp.new("foo")

    => -:2: warning: discarding old =~
       -:8: warning: discarding old =~
       ruby 1.6.5 (2001-09-19) [i586-linux]
       ["Regexp#=~", /foo/, "foo"]
       ["String#=~", "foo", /foo/]

    => -:2: warning: discarding old =~
       -:8: warning: discarding old =~
       ruby 1.6.5 (2001-10-10) [i586-linux]
       0
       ["String#=~", "foo", /foo/]

    (有时会对内部方法进行这种最优化设置,因此可能导致重定义方法无效的情况,而确切地说,您应该先判断某方法是否已被重定义,然后再选择是否进行最优化)
class 定义

    以前,若显式地使用一个不同的超类来重定义某个已定义的类时,则会忽略指定的超类。[ruby-bugs-ja:PR#87]

    class A
      p self.id
    end
    class A < String
      p self.id
      p self.superclass
    end

    => ruby 1.6.5 (2001-09-19) [i586-linux]
       537760880
       -:4: warning: already initialized constant A
       537757180
       Object
    => ruby 1.6.5 (2001-10-10) [i586-linux]
       537760960
       -:4: warning: already initialized constant A
       537757200
       String

%w(...)

    以前,语法解释器会将数组字面值 %w(...)误判为字符串字面值,从而导致下列异常情况。[ruby-bugs-ja:PR#91]

    %w!a! "b"
    => -:1: tried to allocate too big memory (NoMemoryError)
       ruby 1.6.5 (2001-09-19) [i586-linux]

    => -:1: parse error
           %w!a! "b"
                    ^
       ruby 1.6.5 (2001-10-10) [i586-linux]

Thread

    以前存在下列bug:Thread#status对aborting状态返回"run",而Thread#priority = val会返回self而不是val。现已解决这些问题。[rubyist:0820], [ruby-dev:14903]
Marshal

    不能dump无名的类/模块。

    p Marshal.dump(Class.new)

    => ruby 1.6.4 (2001-06-04) [i586-linux]
       "\004\005c\031#<Class 0lx401a6b44>"

    => -:1:in `dump': can't dump anonymous class #<Class 0lx401ab980> (ArgumentError)
            from -:1
       ruby 1.6.5 (2001-10-05) [i586-linux]

UNIXSocket#addr

    以前,UNIXSocket#addr会返回一些垃圾信息(在BSD中如何呢?)。 [ruby-bugs-ja:PR#85]

    # server
    require 'socket'
    File.unlink("/tmp/sss")
    sock = UNIXServer.new("/tmp/sss").accept

    # client
    require 'socket'
    sock = UNIXSocket.new("/tmp/sss").addr

    => ["AF_UNIX", "\031((\306\031(\010"]

    => ["AF_UNIX", ""]

???

    [ruby-talk:21722]

    class Ptr

    def initialize(obj) @obj = obj end
    def []=() @obj = obj end
    def []() @obj end

    end module Kernel

    def _ptr() Ptr.new(self) end

    end

    def foo(int)

    int[] += 1

    end x = 1._ptr foo(x) puts x[]

    => -:11: [BUG] Segmentation fault

    ruby 1.6.5 (2001-09-19) [i586-linux]

    => -:11:in `[]=': wrong # of arguments(1 for 0) (ArgumentError)

    from -:11:in `foo'
    from -:14

    ruby 1.6.5 (2001-10-05) [i586-linux]

Subclass of String and Array

    以前,在String, Array的子类中调用某些特定方法时,就会变成String, Array。

    class Foo < String
    end
    p Foo.new("").type
    p Foo.new("foo")[0,0].type              # String ???
    p Foo.new("foo")[1,1].type
    p Foo.new("foo").succ.type
    p Foo.new("foo").reverse.type
    p((Foo.new("foo") * 5).type)
    p Foo.new("foo").gsub(/foo/, "bar").type
    p Foo.new("foo").sub(/foo/, "bar").type
    p Foo.new("foo").ljust(10).type
    p Foo.new("foo").rjust(10).type
    p Foo.new("foo").center(10).type

    => ruby 1.6.5 (2001-09-19) [i586-linux]
       Foo
       String
       String
       String
       String
       String
       String
       Foo
       String
       String
       String

    => ruby 1.6.5 (2001-10-05) [i586-linux]
       Foo
       String
       Foo
       Foo
       Foo
       Foo
       Foo
       Foo
       Foo
       Foo
       Foo

    class Bar < Array
    end
    bar = Bar.new
    p bar.type
    p bar.push(1,2,3)
    p bar.type
    p bar[0,0].type            # => Array ???
    p bar[0,1].type
    p ((bar * 5).type)

    => -:9: warning: p (...) interpreted as method call
       ruby 1.6.5 (2001-09-19) [i586-linux]
       Bar
       [1, 2, 3]
       Bar
       Array
       Array
       Array
    => -:9: warning: p (...) interpreted as method call
       ruby 1.6.5 (2001-10-05) [i586-linux]
       Bar
       [1, 2, 3]
       Bar
       Array
       Bar
       Bar

1.6.4 (2001-06-04) -> 1.6.5 (2001-09-19)

$_, $~, if a..b

    以前,在函数中使用Thread#run时,与该线程共享scope的父线程中的$_, $~会被子线程所覆盖。[ruby-dev:14743]

    def foo(t)
      t.run
    end

    t = Thread.start do
      t = $_= "sub"
      loop{Thread.stop;puts "sub:#$_"}
    end

    $_ = "main"
    t.run                   # => sub:sub
    puts "main:#$_"         # => main:main
    foo(t)                  # => sub:sub
    puts "main:#$_"         # => main:sub
    => ruby 1.6.4 (2001-06-04) [i586-linux]
       sub:sub
       main:main
       sub:sub
       main:sub
    => ruby 1.6.5 (2001-09-19) [i586-linux]
       sub:sub
       main:main
       sub:sub
       main:main

net/telnet.rb

    有时,当Net::Telnet连接到特定的端口之后,就失去反应。 [ruby-list:31303]
CGI#header

    以前,在下述脚本中,TEXT_PLAIN会被改写成"text/plain; charset=iso-8859-1"。 [ruby-dev:14716]

    require 'cgi'

    TEXT_PLAIN = "text/plain"

    cgi = CGI.new
    print cgi.header("type" => TEXT_PLAIN,
                     "charset" => "iso-8859-1")
    printf("TEXT_PLAIN: %s\n", TEXT_PLAIN)

    => ruby 1.6.4 (2001-06-04) [i586-linux]
       Content-Type: text/plain; charset=iso-8859-1
       ^M
       TEXT_PLAIN: text/plain; charset=iso-8859-1
       TEXT_PLAIN: text/plain

    => ruby 1.6.5 (2001-09-19) [i586-linux]
       Content-Type: text/plain; charset=iso-8859-1
       ^M
       TEXT_PLAIN: text/plain

Dir.chdir

    在尚未定义HOME或LOGDIR时,若不带参数地调用Dir.chdir的话,就会引发ArgumentError异常

    ENV['HOME'] = nil ENV['LOGDIR'] = nil Dir.chdir => -:3:in `chdir': Bad address (Errno::EFAULT)

    from -:3

    ruby 1.6.4 (2001-08-26) [i586-linux]

    => -:3:in `chdir': HOME/LOGDIR not set (ArgumentError)

    from -:3

    ruby 1.6.5 (2001-09-19) [i586-linux]

Dir.glob

    以前,下列代码会引起死循环。

    Dir.mkdir("test?") rescue nil
    p Dir.glob("test?/*")
    => ruby 1.6.5 (2001-09-19) [i586-linux]
       []

jcode.rb

    修改了若干bug。[ruby-list:31238]

Dir.glob

    Dir.glob("*/**/*")会重复返回子目录中的文件。 [ruby-dev:14576]

    Dir.mkdir('foo') rescue nil
    Dir.mkdir('foo/bar') rescue nil
    p Dir.glob('*/**/*')

    => ruby 1.6.4 (2001-06-04) [i586-linux]
       ["foo/bar", "foo/bar"]

    => ruby 1.6.4 (2001-08-26) [i586-linux]
       ["foo/bar"]

UnboundMethod#bind

    无法bind模块的UnboundMethod对象。 [rubyist:0728]

    module Foo
      def foo
        :foo
      end
    end

    class Bar
      include Foo
    end

    m = Foo.instance_method :foo
    p m.bind(Bar.new).call

    => ruby 1.6.4 (2001-06-04) [i586-linux]
       -:12:in `bind': first argument must be an instance of Foo (TypeError)
            from -:12

    => ruby 1.6.4 (2001-08-23) [i586-linux]
       :foo

内部类的替换

    对内部类/模块进行赋值时,会出现警告。

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

    => -:1: warning: already initialized constant Array
       ruby 1.6.4 (2001-08-23) [i586-linux]
       nil

Regexp

    以前,若反向参考中的数字大于括号数量时,则会匹配任何内容。[ruby-list:30975]

    p /(foo)\2/ =~ "foobar"
    => ruby 1.6.4 (2001-06-04) [i586-linux]
       0
    => ruby 1.6.4 (2001-08-23) [i586-linux]
       nil

TCPSocket.open

    修复了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]
       #<Struct::Cat name="dog", age=12, life=7>
    => ruby 1.6.4 (2001-08-06) [i586-linux]
       -:4:in `name=': can't modify frozen Struct (TypeError)
            from -:4

    cat = Struct.new("Cat", :name, :age, :life)
    a = cat.new("cat", 12, 7)
    Thread.new do
       abort_on_exception = true
       $SAFE = 4
       a.life -= 1
    end.join
    p a.life
    => ruby 1.6.4 (2001-06-04) [i586-linux]
       6
    => ruby 1.6.4 (2001-08-06) [i586-linux]
       -:6:in `life=': Insecure: can't modify Struct (SecurityError)
            from -:3:in `join'
            from -:3

String#rindex

    将正则表达式传给rindex时,则会出现bug。[ruby-dev:13843] (该bug出现在1.6.4 版本之后)

    p "foobar".rindex(/b/)
    => ruby 1.6.4 (2001-06-04) [i586-linux]
       3

    => ruby 1.6.4 (2001-06-19) [i386-freebsd5.0]
       nil

    => ruby 1.6.4 (2001-08-06) [i586-linux]
       3

require

    以前,若把以~开头的文件名传给require时必须带上扩展名,否则无法进行加载。[ruby-dev:13756]

    $ echo p __FILE__ > ~/a.rb
    $ ruby17 -v -r~/a -e0
    ruby 1.7.1 (2001-07-03) [i686-linux]
    0: No such file to load -- ~/a (LoadError)
    $ ruby16 -v -r~/a -e0
    ruby 1.6.4 (2001-07-02) [i686-linux]
    0: No such file to load -- ~/a (LoadError)
    $ ruby14 -v -r~/a -e0
    ruby 1.4.6 (2000-08-16) [i686-linux]
    "/home/nobu/a.rb"

String#each_line

    以前,无法正确传递污染。[ruby-dev:13755]

    "foo\nbar\n".taint.each_line {|v| p v.tainted?}
    => ruby 1.6.4 (2001-06-04) [i586-linux]
       false
       true
    => ruby 1.6.4 (2001-08-06) [i586-linux]
       true
       true

NKF::nkf

    以前,无法正确传递污染。[ruby-dev:13754]

    require 'nkf'
    p NKF.nkf("-j", "a".taint).tainted?

    => ruby 1.6.4 (2001-06-04) [i586-linux]
       false
    => ruby 1.6.4 (2001-08-06) [i586-linux]
       true

ruby -x

    指定了-x[directory]选项的话,有时会出现尚未执行脚本就已经结束的情况。[ruby-dev:13752]
attr_*

    向accessor传递多余的参数也不会引起错误。 [ruby-dev:13748]

    class C
      def initialize
        @message = 'ok'
      end
      attr_reader :message
    end
    puts C.new.message(1,2,3)

    => ruby 1.6.4 (2001-06-04) [i586-linux]
       ok
    => ruby 1.6.4 (2001-08-06) [i586-linux]
       -:7:in `message': wrong # of arguments(3 for 0) (ArgumentError)
            from -:7

Readline::completion_append_character
Readline::completion_append_character=

    添加。GNU Readline库中的rl_completion_append_character变量的accessor。(在GNU readline 2.1之后的版本中才能使用该变量) [ruby-ext:01760]
Socket::Constants

    添加了下列socket相关的常数。

    SO_PASSCRED
    SO_PEERCRED
    SO_RCVLOWAT
    SO_SNDLOWAT
    SO_RCVTIMEO
    SO_SNDTIMEO
    SO_SECURITY_AUTHENTICATION
    SO_SECURITY_ENCRYPTION_TRANSPORT
    SO_SECURITY_ENCRYPTION_NETWORK
    SO_BINDTODEVICE
    SO_ATTACH_FILTER
    SO_DETACH_FILTER
    SO_PEERNAME
    SO_TIMESTAMP

require / $LOAD_PATH

    Changed to use a new algorithm to locate a library.

    Now when requiring "foo", the following directories are searched for the library in the order listed.

    $prefix/lib/ruby/site_ruby/$ver/foo.rb
    $prefix/lib/ruby/site_ruby/$ver/foo.so
    $prefix/lib/ruby/site_ruby/$ver/$arch/foo.rb
    $prefix/lib/ruby/site_ruby/$ver/$arch/foo.so
    $prefix/lib/ruby/site_ruby/foo.rb
    $prefix/lib/ruby/site_ruby/foo.so
    $prefix/lib/ruby/$ver/foo.rb
    $prefix/lib/ruby/$ver/foo.so
    $prefix/lib/ruby/$ver/$arch/foo.rb
    $prefix/lib/ruby/$ver/$arch/foo.so
    ./foo.rb
    ./foo.so

    The previous behavior had a potential security risk because a foo.rb (if exists) in the current directory is located prior to a foo.so in $prefix/lib/ruby/site_ruby/$ver/$arch.

    [ruby-bugs:PR#140], [ruby-ext:01778], [ruby-dev:13659]
lib/sync.rb
lib/mutex_m.rb

    Fixed for obj.extend(Sync_m) and obj.extend(Mutex_m).[ruby-dev:13463]

    $ ruby -v -rsocket -rmutex_m -e 's=TCPSocket.new("localhost",25); s.extend(Mutex_m)'
    ruby 1.6.4 (2001-06-04) [i386-linux]
    /usr/lib/ruby/1.6/mutex_m.rb:104:in `initialize': wrong # of arguments (0 for 1) (ArgumentError)
            from /usr/lib/ruby/1.6/mutex_m.rb:104:in `initialize'
            from /usr/lib/ruby/1.6/mutex_m.rb:50:in `mu_extended'
            from /usr/lib/ruby/1.6/mutex_m.rb:34:in `extend_object'
            from -e:1:in `extend'
            from -e:1

$SAFE / load

    以前存在以下bug:在1 <= $SAFE <= 3的情况下,当第二参数为true时,即使指定了被污染的对象名,也能进行load()。现在已经修复该bug。[ruby-dev:13481]

    $SAFE = 1
    filename = "foo"
    filename.taint
    p load(filename, true)

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

    => ruby 1.6.4 (2001-08-06) [i586-linux]
       -:4:in `load': Insecure operation - load (SecurityError)
            from -:4

Regexp

    以前,只有后者能匹配成功。[ruby-talk:16233]

    puts "OK 1" if /(.|a)bd/ =~ "cxbd"
    puts "OK 2" if /(a|.)bd/ =~ "cxbd"

    => ruby 1.6.4 (2001-06-04) [i586-linux]
       OK 2
    => ruby 1.6.4 (2001-08-06) [i586-linux]
       OK 1
       OK 2

Marshal

    以前,模块加载时的类型检测中存在错误。修复该错误后,dump format的minor版本号升高1级

    p Marshal.dump(Object.new).unpack("CC").join(".")
        => ruby 1.6.4 (2001-06-04) [i586-linux]
           "4.5"
    p Marshal.dump(Object.new).unpack("CC").join(".")
        => ruby 1.6.4 (2001-06-11) [i586-linux]
           "4.6"

$SAFE / def

    虽然doc/NEWS中有下列内容

    Fixed so defining a new method is allowed under $SAFE == 4, which
    previously wasn't.

    但实际上是行不通的。

    $SAFE = 4; def a; end

    => -:1: Insecure operation `(null)' at level 4 (SecurityError)
       ruby 1.6.4 (2001-06-04) [i586-linux]

    => -:1: Insecure: can't define method (SecurityError)
       ruby 1.6.4 (2001-08-06) [i586-linux]

    对应的ChangeLog内容如下。

    Tue Jun  5 15:16:06 2001  Yukihiro Matsumoto  <[email protected]>

            * 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 #<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]

    允许使用

你可能感兴趣的:(thread,linux,socket,正则表达式,Ruby)