Ruby Ruby 2.5.0 已发布

dsh0416 · 2017年12月25日 · 最后由 runup 回复于 2018年02月06日 · 13039 次阅读
本帖已被管理员设置为精华贴

翻译自:https://www.ruby-lang.org/en/news/2017/12/25/ruby-2-5-0-released/

我们高兴地宣布 Ruby 2.5.0 已发布。

Ruby 2.5.0 是 2.5 系列首个稳定版。此版本包括数个新特性和性能提升,例如:

新特性

  • 允许在 do/end 中直接使用 rescue/else/ensure。[功能 #12906]
  • 新增 yield_self 来使用当前上下文 yield 代码块。不同于 tap,此方法会返回代码块的运行结果。[功能 #6721]
  • 支持测量分支代码覆盖和方法代码覆盖。分支代码覆盖指检查哪些分支被覆盖到,哪些没有。而方法覆盖在指可以测量方法是否被调用。基于这些新特性运行你的测试用例,你可以精确地知道哪些分支和方法被运行,并更精确地计算测试的代码覆盖程度。[功能 #13901]
  • 新增 Hash#slice [功能 #8499] 和 Hash#transform_keys。[功能 #13583]
  • Struct.new 现在可以被用于创建含有关键字参数的类。[功能 #11925]
  • Enumerable#any?, all?, none? 和 one? 可以接受一个模式作为参数。[功能 #11286]
  • 删除顶层常量查找。[功能 #11547]
  • 我们最喜爱的库之一 pp.rb,现已自动加载。无需手动写 require "pp" 来加载。[功能 #14123]
  • 逆序打印(从旧到新)调用跟踪和错误消息。当在终端(TTY)中用较长的调用跟踪信息时,你可以从最底部看到直接触发问题的行。需要注意的是,仅当在直接输出到终端时,才会逆序打印。[功能 #8661] [试验性]

性能提升

  • 通过在字节码中移除了全部 trace 指令提升了大约 5-10% 的性能。trace 指令的引入是为了提供 TracePoint 的支持。然而,在大多数情况,TracePoint 不会被用到,trace 指令增加了额外的开销。作为替代,我们实现了一个动态指令技术,详情见 [功能 #14104]
  • 通过懒惰 Proc 分配使 block 参数传递代码块(例如 def foo(&b); bar(&b); end)的性能相较于 Ruby 2.4 提升了约 3 倍。[功能 #14045]
  • 互斥锁的复写变得更轻量和快速。[功能 #13517]
  • ERB 现在模板生成代码的速度相较于 Ruby 2.4 提升 2 倍。
  • 提升了多个内置方法例如 Array#concat, Enumerable#sort_by, String#concat, String#index, Time#+ 等。
  • IO.copy_stream 使用 copy_file_range(2) 来拷贝负载。[功能 #13867]

与 2.4 相比的重要变化

  • SecureRandom 倾向使用操作系统方法而非 OpenSSL。[漏洞 #9569]
  • 将 cmath, csv, date, dbm, etc, fcntl, fiddle, fileutils, gdbm, ipaddr, scanf, sdbm, stringio, strscan, webrick, zlib 从标准库中提升到默认 gem。
  • 升级 Onigmo 到 6.1.3。
  • 更新到 Psych 3.0.2。
  • 更新到 Rubygems 2.7.3。
  • 更新到 RDoc 6.0.1。
  • 更新到 Unicode 10.0.0。
  • Thread.report_on_exception 默认值现为 true,这对调试多线程程序很有帮助。[功能 #14143]
  • IO#write 现接受多个参数 [功能 #9323]

详见 NEWS提交记录以查看详情。

自 Ruby 2.4.0 以来,已有 6158 个文件更改,348484 行增加 (+),82747 行删减 (-)

圣诞快乐!享受你 Ruby 2.5 的编程之旅吧!

下载

  • https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0.tar.gz

    SIZE:   15834941 bytes
    SHA1:   58f77301c891c1c4a08f301861c26b1ea46509f6
    SHA256: 46e6f3630f1888eb653b15fa811d77b5b1df6fd7a3af436b343cfe4f4503f2ab
    SHA512: 0712fe68611f5d0cd6dd54b814f825478e64b6a62bdf67bce431f4dca2dc00b1a33f77bebfbcd0a151118a1152554ab457decde435b424aa1f004bc0aa40580d
    
  • https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0.zip

    SIZE:   19495617 bytes
    SHA1:   700b6f55d689a5c8051c8c292b9e77a1b50bf96e
    SHA256: 94559ea6e3c619423da604e503ce1dc1c465d6e0747a07fbdc5f294acaf14c24
    SHA512: e4324064cee8c65b80192e3eff287e915d2d40464d300744c36fb326ae4b1846911400a99d4332192d8a217009d3a5209b43eb5e8bc0b739035bef89cc493e84
    
  • https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0.tar.bz2

    SIZE:   13955820 bytes
    SHA1:   827b9a3bcffa86d1fc9ed96d403cb9dc37731688
    SHA256: d87eb3021f71d4f62e5a5329628ac9a6665902173296e551667edd94362325cc
    SHA512: 8f6fdf6708e7470f55bc009db2567cd8d4e633ad0678d83a015441ecf5b5d88bd7da8fb8533a42157ff83b74d00b6dc617d39bbb17fc2c6c12287a1d8eaa0f2c
    
  • https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0.tar.xz

    SIZE:   11292472 bytes
    SHA1:   9c7babcf9e299be3f197d9091024ae458f1a1273
    SHA256: 1da0afed833a0dab94075221a615c14487b05d0c407f991c8080d576d985b49b
    SHA512: 55714a33d7661fe8b432f73c34fd67b49699f8b79df1cbd680a74899124d31111ab0f444677672aac1ba725820182940d485efb2db0bf2bc96737c5d40c54578
    
lgn21st 将本帖设为了精华贴。 12月25日 20:18

谢谢 Matz 坚持每年给大家带来最好的圣诞礼物,也谢谢队长 @dsh0416 辛苦翻译,Ruby 加油!

谢谢队长中文化,我也只能贡献点支持啦

原文没写 bundler 纳入标准库哦。

赞,终于有和 python 一样的逆序打印了

Rei 回复

谢谢提醒,因为前几项和 rc1 版本一样我拿过来了🤦‍♀️

升级然后跑崩了,多个 gem 有此问题,这个没办法接受:

$ irb
irb(main):001:0> def m(arg, &block)
irb(main):002:1>   pp arg
irb(main):003:1>   block.call
irb(main):004:1> end
=> :m
irb(main):005:0> m(100) { puts "block" }
100
block
=> nil
irb(main):006:0> m 100 { puts "block" }
Traceback (most recent call last):
        1: from /home/ruby/.rbenv/versions/2.5.0/bin/irb:11:in `<main>'
SyntaxError ((irb):6: syntax error, unexpected '{', expecting end-of-input
m 100 { puts "block" }
      ^)
irb(main):007:0>

以前很多代码都是这样写的! method arg { block }

其实严谨些是这样的写法好。method(arg) { block }

后端渲染肯定比前端渲染加载速度快。 当服务器压力大时怎么办:负载均衡,能用机器解决的问题,就不要用人力来解决 这样的断言有问题吗

比较关心的是 break changes,居然没发现, #9 楼的看到怕了...

yield_self 点赞,链式写法一链到底

Thread.report_on_exception 改成 true 了,那我得改下我的线程实现了

ERB 现在模板生成代码的速度相较于 Ruby 2.4 提升 2 倍
zhangzitao 回复

看成本问题

# coding=GBK
puts RUBY_VERSION
'中国11111'.each_char do |char|
 puts "%s %3d %02X" % [ char, char.ord, char.ord ]
end  

文件保存成 gbk ruby 2.5 运行报错 invalid multibyte char (UTF-8) ruby 2.0 正常

那么,用 2.5.0 自带的 erb 来渲染模板的话,比用 gem erubi 要来得快么?

gihnius 回复

{ } 块绑定到最近的对象。method arg { block } 实际是 method(arg { block }),所以 m 100 { puts "block" } 报错是很正常的也是正确的。

如果需要你想要的行为,你需要使用 do... end 块。

等 2.5.1 出了就升级

我不这样写,但问题是之前的版本没有报错,现在 2.5.0 报错。

更新看到性能提升方面😁 ,内心难免有点小鸡动呢

banana 回复

2.6 的性能提升会更加明显,JIT is coming...

banana 回复

不是每一版都有性能提升吗……

jasl 回复

2.6 的 JIT 可能不会被编译,需要手动开启编译选项才行。。。

dsh0416 回复

但是可以开了嘛,就跟 jemalloc 一样

jasl 回复

jemalloc 这玩意好是好,就是没见过几个人用(逃

dsh0416 回复

jemalloc 开了出 bug 就很讨厌,希望 mjit 不会

gihnius 回复

至少 1.9 里面这样写就报错了,你是不是看错代码了。

29 楼 已删除

从 2.4.0 升到 2.5.0 看到这个报错。

例子 https://mensfeld.pl/2017/12/ruby-2-5-0-upgrade-remarks/

好像旧的有些版本会有报错,有些没有报,奇怪。

gihnius 回复

这其实是一个回归问题,报错的复现是:

[].delete 1 { 'NG' }

在 Ruby 2.3 系列以及更早的 Ruby 版本中,从 2.3.0 到 Ruby 2.3.5 中,这个语法是非法的,会报错。

❯ ruby --dump=parsetree -vwce "[].delete 1 { 'NG' }"
ruby 2.3.5p376 (2017-09-14 revision 59905) [x86_64-darwin17]
-e:1: syntax error, unexpected '{', expecting end-of-input
[].delete 1 { 'NG' }

在 Ruby 2.4.0、Ruby 2.4.1 中,会返回 NG

parser 的结果如下:

❯ ruby --dump=parsetree -vwce "[].delete 1 { 'NG' }"
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin16]
Syntax OK
###########################################################
## Do NOT use this node dump for any purpose other than  ##
## debug and research.  Compatibility is not guaranteed. ##
###########################################################

# @ NODE_SCOPE (line: 1)
# +- nd_tbl: (empty)
# +- nd_args:
# |   (null node)
# +- nd_body:
#     @ NODE_PRELUDE (line: 1)
#     +- nd_head:
#     |   (null node)
#     +- nd_body:
#     |   @ NODE_ITER (line: 1)
#     |   +- nd_iter:
#     |   |   @ NODE_CALL (line: 1)
#     |   |   +- nd_mid: :delete
#     |   |   +- nd_recv:
#     |   |   |   @ NODE_ZARRAY (line: 1)
#     |   |   +- nd_args:
#     |   |       @ NODE_ARRAY (line: 1)
#     |   |       +- nd_alen: 1
#     |   |       +- nd_head:
#     |   |       |   @ NODE_LIT (line: 1)
#     |   |       |   +- nd_lit: 1
#     |   |       +- nd_next:
#     |   |           (null node)
#     |   +- nd_body:
#     |       @ NODE_SCOPE (line: 1)
#     |       +- nd_tbl: (empty)
#     |       +- nd_args:
#     |       |   (null node)
#     |       +- nd_body:
#     |           @ NODE_STR (line: 1)
#     |           +- nd_lit: "NG"
#     +- nd_compile_option:
#         +- coverage_enabled: false

这是一个不符合预期的 parser 行为,所以应该被移除。移除的工作发生在 Ruby 2.5.0 的开发过程中,见:Issue #13547

因此,在 Ruby 2.5.0 中,该行为已被修复。但是需要注意的是,这不止是 Ruby 2.5 系列才这么进行了修改,Ruby 2.4.2 同样也解决了这个回归问题。

这引发了另一个 Issue, Issue #13898,说的是 Ruby 2.4.2 作为小版本更新,是否应该保持和 2.4.0、2.4.1 的向后兼容。目前该 Issue 已被 Rejected,回归问题可能不作为向后兼容的考虑。

yield_self 帮了大忙,看到这个还蛮兴奋的

第一次经历新版本更新,这种感觉就是像苹果发布新电脑一样的感觉吗?

Awlter1 回复

我觉得 2.6 发布应该会有类似 iPhone X 的感觉

jasl 回复

已经有铁粉在谋划到日本排队领取最新版的 Ruby2.6,还有机会让 Matz 亲手为你编译。我还有个朋友,准备到时候买 10 套港版 Ruby2.6 先带回国内卖。

37 楼 已删除
38 楼 已删除
39 楼 已删除

😀 😮 已经更新

需要 登录 后方可回复, 如果你还没有账号请 注册新账号