Ruby 1.9的一些新特性,从RMXP/VX转到VA上时可作参考

1. RPG Maker VX Ace添加了控制台,p、print方法不再弹出窗口,
若需要弹出窗口,则可以使用msgbox或msgbox_p方法。

2. Ruby 1.9 允许带有缺省值的参数放在前面了

def f(a=1, b); p [a,b]; end;
p f(2) # => [1, 2]

3. Ruby 1.9 允许你把可变参数放在参数列表的任何位置

def a(a,*b,c); p [a,b,c]; end
p a(1,2,3,4) # => [1, [2, 3], 4]

注:带缺省值的参数必须挨在一起,如下情况是不合语法的:

def bar(a, b = nil, c, d = nil, e)
 p [ a, b, c, d, e ]
end

这可能是由于 Ruby 解释器使用的 LR(1) 解析器不能轻易处理这种情况。
带缺省值参数和可变长度参数列表可以混用,但前者必须出现在后者之前。

def foo(a = 0, *args)
    p [a, args]
end
foo(5, 6, 7, 8) # => [5, [6, 7, 8]]
foo()           # => [0, []]

4. Ruby 1.9 加入了一个 Hash#assoc 方法,返回 [key, hsh[key]]

p({a: 1, b: 2}.assoc(:b)) # => [:b, 2]

5. Ruby 1.9.X 能对符号(Symbol)使用正则式了

p :ruby_symbol.match(/symbol/) # => 5

6. Ruby 1.9.X 提供了一种新的建立Hash的方法

p({a:1, b:2}) # => {:a=>1, :b=>2}

注:注意这种新的 Hash 字面值只针对于符号键。

7. Ruby 1.9 不再支持 String#each ,如有需要,
请使用chars,bytes,lines,each_char等方法
注:在1.8中,取string里的一个字符会得到一个整数,
其值是那个字符的ASCII码,庆幸的是在1.9这个缺陷得到了改变,
取出的将是一个只包含那个字符的string对象

a = "ABC"
p a[0]
#=> 65 in Ruby 1.8
#=> "A" in Ruby 1.9

8. Ruby 1.9 添加了 Enumerable#sample(n) 方法,随机抽出 n 个元素

p [1,2,3,4].sample(2)  # => [2, 3]

9. Ruby 1.9 添加了Kernel#define_singleton_method 函数

c = 'cat'; c.define_singleton_method(:hi) { p 'hi' };
p c.hi  # => "hi"

10. Ruby 1.9 提供了能创建生命周期只在块中的临时变量

v = 'ruby'; [1,9].map {|val; v| v = val }
p v # => "ruby"

注:在神奇的Ruby中,for i in 0..5; end; p i # => 5

11. Ruby 1.9 允许块使用块作为参数了

b = -> v, &blk { p [v, blk.call] }
p b.call(:a) { :b } # => [:a, :b]

注:块的参数在 Ruby 1.8 中并不一定是局部的,如果外部有同名变量,
那么它引用的仍然是外部的同名变量。
在1.8中,代码中的块变参数赋值会改变块外部变量的值:

l1 = l2 = 1
lambda{ |l1, l2|
        p "参数是#{l1},#{l2}"
        l1 = 1234567
        l2 = 7654321
}.call(126, 127)
p l1 # => 1234567
p l2 # => 7654321

而在 Ruby 1.9 中,块的参数永远是局部的。

12. Ruby 1.9 added Process.spawn which will execute cmd in subshell

pid = spawn('echo hello')
  p Process::waitpid2(pid)  # => [62777, #]

13. Ruby 1.9 added Enumerable.reduce, which is equivalent to Enumerable.inject

p [1,2,3].reduce(:+)  # => 6

14. 和其他的语言不一样,Ruby的常量(Constant)可在初始化后改变其值

test.rb
  Apple = "Newton"
  Apple = "Jobs"
ruby test.rb
"test.rb:2: warning: already initialized constant Apple"
ruby -W0 test.rb
""
ruby -W1 test.rb
"test.rb:2: warning: already initialized constant Apple"

在默认情况下运行,程序对你说:嗨,你已经初始化了Apple这个常量,
当然,他只是警告你,而程序继续运行。试试将安全等级设置低一点。
ruby.exe 支持一个参数叫做安全等级,表示为 -W[0|1|2]。
由于默认是第二等级,verbose,因此我们只需要测试0和1的情况。
当安全等级为0时他就不发牢骚了。当然在RPG Maker里,也不会发牢骚。
更改常量只能在顶层或类/模块定义中,而不能在一个方法中。

15. Ruby 1.8 的 Kernel#require 可以接受一个绝对路径,
如果不是绝对路径,就会在 $: 保存的搜索路径中进行搜索,
但这默认不包括当前工作路径。
Ruby 1.9 多了个 Kernel#require_relative,接受相对于当前源文件的路径,
这样就不用显示地去把当前工作路径添加到 $: 中或显示地指定 `.' 了。
要注意的是 irb 中无法使用这个函数,因为 irb 并没有明确的源文件定义。

16. 数组的.to_s方法,改为输出人类可读的形式

p [1,2,3].to_s #=> "[1,2,3]"  in Ruby 1.9
p [1,2,3].to_s #=> "123"  in Ruby 1.8

注:过滤字符串后配合eval方法,再也不用头疼Array和Stirng的互相转换了

17. Ruby 1.9 Symbol自带.to_proc方法了

words = %w(hello kitty not world)
list = words.map(&:capitalize)
p list # => ["Hello", "Kitty", "Not", "World"]

18. 新的转义序列:\u
在字符串字面值中指定 \u 可以用来表式一个 Unicode 字符,
后面紧跟着一个 16 位(双字节 UTF-16BE)十六进制数字:

#coding: GBK
str = "测试".encode(Encoding::UTF_16BE)
p "\u6d4b\u8bd5".encoding
p "\u6d4b\u8bd5".encode(Encoding::GBK, Encoding::UTF_8)
p "\u6d4b\u8bd5".encode(Encoding::GBK)

当字符串中包含 \u 序列时,尽管指定的是 UTF-16 大端序的 Unicode 字符,
该字符串还是会被自动编码为 UTF-8,并相应设置字符串的编码成员为 UTF-8
`\u6d4b' 和 `\u8bd5' 这两个字符分别是 `测' 和 `试' 的 UTF-16BE 内码。
后两行输出完全一致,因为字符串对象内部维护着一个编码对象的域,所以,
String#encode 根据这个域进行编码,它知道"\u6d4b\u8bd5"的编码为 UTF-8
String#force_encoding,强行改变字符串对象的编码属性,但是,它并不会改
变底层内码,只是改变其它编码的方法(如String#encode)处理字符串的行为。

#coding: GBK
str_utf_8 = "测试"
str_gbk = str_utf_8.clone
str_gbk.force_encoding(Encoding::UTF_8)
p str_gbk.encode(Encoding::GBK)

输出:
1.rb:7:in `encode': "\xB2" on UTF-8 (Encoding::InvalidByteSequenceError) from 1.rb:7:in `'
String#encode 把 str_gbk 当做 GBK 编码来处理,而 str_gbk 的内码,
实际上还是 UTF-8,所以抛出了这个异常。
可以用 String#valid_encoding? 来对此进行判断。

19. Ruby 1.9 引入了纤程(Fiber)的概念。

20. 随着我们对 Hash 的了解越深,“Hash 不保证顺序”的概念越来越深入脑海
然而,顽皮的 Ruby 又一次颠覆了用户的观念:Hash 也可以是有序的!
在 1.8 中,Hash 对象即是使用分离链接法解决哈希碰撞的散列表。
每项需要4个东西:散列码、键的引用、值的引用、下个散列码相同元素的引用
为了实现有序的散列表,Ruby 1.9 在表的元素结构体中增加了两个新的指针:
指向按顺序排列的前一个和后一个元素的指针,
这使得在对散列表进行插入和删除操作时能够维护一个有序的链,
实际上就是一个和旧的散列表结构穿插在一起的双向循环链表结构,
这两种结构的并集就是新的 Hash 结构了。
这个改动的代价是:1.9 的 Hash 的 插入和删除变得更慢了些。
这个改动的好处是:Hash 的遍历、迭代、枚举也有序了,同时,
因为内部维护着双向循环链表,1.9 遍历 Hash 的速度也比 1.8 快,
因为 1.8 必须要遍历整个散列表的桶,自然也就必须经过一些桶中的空位。

大部分整理自:rm.66rpg.com/forum.php?mod=viewthread&tid=154785
值得注意的大概就是这些了

发布者

ML4455739

宣传站维护团队

发表评论

电子邮件地址不会被公开。