Ruby 2.6 新特征

Ruby 2.6 新特征 首页 / Ruby入门教程 / Ruby 2.6 新特征

Ruby 2.6在圣诞节那天发布, 并带来了一些有趣的新函数。 以下是更改内容的快速摘要。 和以前版本的摘要一样 ( 2.5 2.4 2.3 ) 只是总结一下觉得最有趣的函数。 有关更改的完整列表, 看看 更改日志

Endless ranges

引入了新的语法以表示无限范围。 在case语句中匹配范围时,这将很有用。

case n
when 1..9 then 'Single digit'
when 10..99 then 'Two digit'
when 100.. then 'Three or more'
end

以前,(1 ..)将表示为(1..Float ::INFINITY)。 

Proc,lambda和Method

#>> 和 #<< 方法已添加到 ProcMethod 对象中,以允许将它们组成一个新方法。

square = -> (n) { n * n }
add_2  = -> (n) { n + 2 }

(square >> add_2).call(5) #=> 27
(square << add_2).call(5) #=> 49

使用 #>> 操作,数字将首先平方,然后对第一个proc调用的结果执行 add_2。在 #<<的情况下,调用proc的顺序相反。

无涯教程希望没有两种不同的proc编写方式,而只使用 #>>。但是合成是Ruby的重要补充,它将使能够以更具函数性的风格进行编写。

Kernel#then

这不是新函数, 但是Kernel#yield_self的别名 是Ruby 2.5中引入的 并允许进行连锁经营 进入这样的管道:

isbn = '978-1-93778-549-9'

isbn.gsub('-', '')
  .then { |isbn| URI("#{API_URL}?q=isbn:#{isbn}") }
  .then { |uri| Net:HTTP.get(uri) }
  .then { |json_response| JSON.parse(json_response) }
  .then { |response| response.dig('items', 'volumeInfo') }

Enumerable#chain and Enumerator#+

这会返回一个 Enumerator ::Chain 对象, 它可以作为单个枚举器使用。

(1..3).chain((5..7), [9, 10]).to_a
#=> [1, 2, 3, 5, 6, 7, 9, 10]

list = (1..3).each + (5..7) + (9..10)
list.to_a
#=> [1, 2, 3, 5, 6, 7, 9, 10]

合并多个哈希

Hash#merge仅接受了一个参数,直到2.5。 合并两个以上哈希的唯一方法 是将呼叫链接到#merge 。 现在,您可以将多个哈希传递给该方法。

foo = { a: 1 }
bar = { b: 2 }
baz = { c: 3 }

foo.merge(bar, baz) #=> { a: 1, b: 2, c: 3 }

# ruby 2.5
# foo.merge(bar).merge(baz)

Array#union and Array#difference

这些方法的工作原理与 | 和 & 运算符。不同之处在于它们可以接受多个参数并且更易于链接。

a = [1, 1, 2, 3]
b = [3, 4]

a.union(b) #=> [1, 2, 3, 4]
a.difference(b) #=> [1, 1, 2]

Enumerable#to_h

现在,Enumerable#to_h 接受了一个将键映射到值的块。 这使能够转换散列 无需使用map创建中间数组, 或使用 reduce 语法。

hash = { foo: 2, bar: 3 }
hash.to_h { |k, v| [k.upcase, v*v] } #=> { FOO: 4, BAR: 9 }

# ruby 2.5:
# hash.map { |k, v| [k.upcase, v*v] }.to_h
# hash.reduce({}) { |result, (k, v)| result.merge(k.upcase => v) }

Enumerator::ArithmeticSequence

Enumerator的子类 被介绍来代表 通过调用Step创建的对象 在RangeNumeric对象上。 这使得做类似的事情成为可能 检查序列是否相等。

r1 = (1..10).step(2)
r2 = (1..10).step(2)

r1 == r2 #=> true if 2.6, false in 2.5
1.step == (1..).step #=> true

Range 变化

运算符 已作为step的别名添加。 因此(1..10)%2 等效于(1..10).step (2)

(a..b).cover?(x) 检查 a <= x < b,而 (a..b).include?(x) 遍历该范围并检查是否有任何元素等于x。这使无涯教程可以执行以下操作:

case DateTime.now
when Date.today..Date.today+1
  puts 'matched'
else
  puts 'not matched'
end

注意: 在本文的早期版本中,在示例中使用了字符串范围。 为了向后兼容, 字符串范围的行为没有改变。

('a'..'c').cover?('bb')   #=> true
('a'..'c').include?('bb') #=> false

case 'bb'
when 'a'..'c' then 'matched'
else 'not matched'
end
#=> 'not matched'

Kernel exception 关键字

Exception关键字参数 为某些Kernel方法像IntegerFloatSystem。 对于Numeric方法, 现在可以传递Exception:false 为了避免在解析无效值时加注, 并返回 nil

另一方面Kernel#system , 接受exception:true 如果命令以非零退出状态退出 (而不是返回false) 或者命令执行失败 (而不是返回nil )。

Integer('foo', exception: false) #=> nil
Float('foo', exception: false) #=> nil

system('foo', exception: true) #=> exception

性能提升

性能方面的最大新闻 是一个JIT实现, 叫 MJIT , 被合并为Ruby。 可以启用 使用-jit 标志。

MJIT导致微基准测试的加速, 但还不够成熟 在较大的代码库(如Rails应用程序)中工作。 对于Rails,它甚至比非JIT版本慢。

但是,这是重要的一步 朝着Ruby 3x3目标迈进, 就是让Ruby 3 至少比Ruby 2.0快3倍。 目前,带有JIT的Ruby 2.6是 比2.0快近2.5倍 在Optcarrot基准测试中, 使用哪个 比较性能 Ruby版本 3x3的目标。

除此之外, 第二个垃圾收集堆, 称为瞬时堆, 被介绍了 减少内存使用 并提高了GC速度 寿命短的物体 Proc.call block.call

其他变化

  • flip flop 运算符最终被弃用, 并可能会在Ruby 3中删除。
  • Bundler现在是默认gem, 因此您不再需要gem安装捆绑程序 安装Ruby之后。 Rubygems 3.0.1也被合并到Ruby中。
  • 添加了Array#filter作为#select的别名。
  • 先前版本的ruby警告 如果您在 begin 块中有一个 else 子句 没有rescue。 这将在2.6中导致语法错误。
begin
  puts 'begin'
else
  puts 'else'
end

# Ruby 2.6
#=> foo.rb:5: else without rescue is useless

# Ruby 2.5
#=> foo.rb:7: warning: else without rescue is useless
#=> begin
#=> else

祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)

技术教程推荐

Nginx核心知识150讲 -〔陶辉〕

从0开发一款iOS App -〔朱德权〕

SRE实战手册 -〔赵成〕

Kafka核心源码解读 -〔胡夕〕

分布式数据库30讲 -〔王磊〕

零基础实战机器学习 -〔黄佳〕

说透低代码 -〔陈旭〕

JavaScript进阶实战课 -〔石川〕

手把手带你搭建推荐系统 -〔黄鸿波〕

好记忆不如烂笔头。留下您的足迹吧 :)