Ruby Ruby 2.5.0 已发布

dsh0416 · December 25, 2017 · Last by runup replied at February 06, 2018 · 13036 hits
Topic has been selected as the excellent topic by the admin.

翻译自: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 mark as excellent topic. 25 Dec 20:18

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

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

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

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

Reply to 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 倍
Reply to 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 要来得快么?

Reply to gihnius

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

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

等 2.5.1 出了就升级

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

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

Reply to banana

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

Reply to banana

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

Reply to jasl

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

Reply to dsh0416

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

Reply to jasl

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

Reply to dsh0416

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

Reply to gihnius

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

29 Floor has deleted

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

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

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

Reply to 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 帮了大忙,看到这个还蛮兴奋的

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

Reply to Awlter1

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

Reply to jasl

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

37 Floor has deleted
38 Floor has deleted
39 Floor has deleted

😀 😮 已经更新

You need to Sign in before reply, if you don't have an account, please Sign up first.