Ruby 2.5 cho ra mắt class FrozenError

Hiện tại Ruby 2.5 đã được release. Vậy chúng mình cùng xem có những gì mới nhé.

1. Class FrozenError

Ruby 2.5 đã giới thiệu class FrozenError là 1 subclass của RuntimeError. Thay đổi này được áp dụng để phân biệt các trường hợp ngoại lệ được tạo ra từ những hành động cố gắng thay đổi frozen object từ các exception thông thường. Chúng ta hãy xem một số ví dụ dưới đây để có thể thấy sự thay đổi nhé.

1.1 String

Prior to Ruby 2.5

2.4.0 :001 > NAME = 'Viblo'.freeze
 => "Viblo"
2.4.0 :002 > NAME << 'PRO'
RuntimeError: can't modify frozen String
 from (irb):2
 from /Users/atul/.rvm/rubies/ruby-2.4.0/bin/irb:11:in `<main>'

Ruby 2.5

2.5.0 :001 > NAME = 'Viblo'.freeze
 => "Viblo" 
2.5.0 :002 > NAME << 'PRO'
Traceback (most recent call last):
        2: from /home/atul/.rvm/rubies/ruby-2.5.0/bin/irb:11:in `<main>'
        1: from (irb):2
FrozenError (can't modify frozen String)

1.2 Array

Prior to Ruby 2.5

2.4.0 :001 > a = [1, 2, 3]
 => [1, 2, 3]
2.4.0 :002 > a.freeze
 => [1, 2, 3]
2.4.0 :003 > a << 4
RuntimeError: can't modify frozen Array
 from (irb):3
 from /Users/atul/.rvm/rubies/ruby-2.4.0/bin/irb:11:in `<main>'

Ruby 2.5

2.5.0 :001 > a = [1, 2, 3]
 => [1, 2, 3] 
2.5.0 :002 > a.freeze
 => [1, 2, 3] 
2.5.0 :003 > a << 4
Traceback (most recent call last):
        2: from /home/atul/.rvm/rubies/ruby-2.5.0/bin/irb:11:in `<main>'
        1: from (irb):3
FrozenError (can't modify frozen Array)

1.3 Hash

Prior to Ruby 2.5

2.4.0 :001 > h = {a: 1}
 => {:a=>1}
2.4.0 :002 > h.freeze
 => {:a=>1}
2.4.0 :003 > h.delete(:a)
RuntimeError: can't modify frozen Hash
 from (irb):3:in `delete'
 from (irb):3
 from /Users/atul/.rvm/rubies/ruby-2.4.0/bin/irb:11:in `<main>'

Ruby 2.5

2.5.0 :001 > h = {a: 1}
 => {:a=>1} 
2.5.0 :002 > h.freeze
 => {:a=>1} 
2.5.0 :003 > h.delete(:a)
Traceback (most recent call last):
        3: from /home/atul/.rvm/rubies/ruby-2.5.0/bin/irb:11:in `<main>'
        2: from (irb):3
        1: from (irb):3:in `delete'
FrozenError (can't modify frozen Hash)

1.4 Object

Prior to Ruby 2.5

2.4.0 :001 > o = Object.new.freeze
 => #<Object:0x007fce5919ad50>
2.4.0 :002 > o.taint
RuntimeError: can't modify frozen Object
 from (irb):2:in `taint'
 from (irb):2
 from /Users/atul/.rvm/rubies/ruby-2.4.0/bin/irb:11:in `<main>'

Ruby 2.5

2.5.0 :001 > o = Object.new.freeze
 => #<Object:0x000055c909144ce0> 
2.5.0 :002 > o.taint
Traceback (most recent call last):
        3: from /home/atul/.rvm/rubies/ruby-2.5.0/bin/irb:11:in `<main>'
        2: from (irb):2
        1: from (irb):2:in `taint'
FrozenError (can't modify frozen Object)

2. rescue/else/ensure

Hiện bản Ruby 2.5 bạn có thể viết rescue/else/ensure mà không cần thiết phải có từ khóa begin/end nằm trong khối do/end Prior to Ruby 2.5

[1].each do |n|
  n / 0
rescue
  # rescue
else
  # else
ensure
  # ensure
end

Ruby 2.5

[1].each { |n|
  n / 0
rescue
  # rescue
else
  # else
ensure
  # ensure
}
#=> SyntaxError: (irb):3: syntax error, unexpected keyword_rescue, expecting '}'
#     rescue
#     ^~~~~~

Bài viết trên chủ yếu giới thiệu về class FrozenError vì vậy nếu muốn biết chi tiết hơn về một số cập nhật mới của Ruby 2.5 bạn có thể truy cập vào địa chỉ sau: https://blog.jetbrains.com/ruby/2017/10/10-new-features-in-ruby-2-5/