1. rescue/else/ensure are allowed inside do/end blocks without begin/end

You can write rescue/else/ensure clauses without begin/end keyword within do/end blocks:

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

But you’ll get an error if you use {} blocks:

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

Feature #12906: do/end blocks work with ensure/rescue/else

2. Top-level constant lookup is removed

In Ruby 2.5, Ruby won’t look up superclass. So the code fails with error:

class Staff; end
class ItemsController; end

Staff::ItemsController
#=> NameError: uninitialized constant Staff::ItemsController
#   Did you mean?  ItemsController

Feature #11547: remove top-level constant lookup

3. Bundler gem is now bundled

Bundler is bundled as a standard library. So you can use it without gem install bundler!

$ ruby -v
ruby 2.5.0preview1 (2017-10-10 trunk 60153) [x86_64-darwin16]
$ bundler -v
Bundler version 1.15.4

Feature #12733: Bundle bundler to ruby core

4. Print backtrace and error message in reverse order (experimental)

In Ruby 2.5:

$ ruby ./test/error_example.rb
Traceback (most recent call last):
        3: from ./test/error_example.rb:10:in `'
        2: from ./test/error_example.rb:2:in `method_1'
        1: from ./test/error_example.rb:7:in `method_2'
./test/error_example.rb:7:in `/': divided by 0 (ZeroDivisionError)

Feature #8661: Add option to print backstrace in reverse order(stack frames first & error last)

5. Kernel#yield_self

Kernel#yield_self is introduced. This method takes a receiver as a block argument and returns a block value as it is:

2.yield_self { |n| n * 10 } #=> 20
 
names = ['Alice', 'Bob']
names.join(', ').yield_self { |s| "(#{s})" } #=> "(Alice, Bob)"

Feature #6721: Object#yield_self

6. More public Module methods

(Features #14132 and #13133).

Module#attr, attr_accessor, attr_reader, attr_writer, define_method, alias_method, undef_method and remove_method are now all public.

For example:

# Ruby v2.5
Integer.alias_method :plus, :+

This update follows nicely from similar changes back in Ruby v2.1.0, where Module#include and Module#prepend were made public.

7. String#start_with? supports regexp

(Feature #13712).

The mistake arrises because, unlike most other languages, the ^ anchor means “starts of line” in ruby; not “start of string”. (That’s what \A is for.)

So, that first line of code would also return true when string = “123\ntest”.

Using the new String#start_with? method, such a mistake wouldn’t happen:

# Ruby v2.5
string.start_with?(/[a-z]/) # Also good

8. Improvements to binding.irb

(Features #13099 and #14124).

As of ruby v2.5, we see two enhancements to the library that help bridge the gap, and make it a little less likely to feel the need for pry in every application:

require ‘irb’ is no longer needed in your code, in order to invoke binding.irb.
Show source around binding.irb is now shown on startup.

# Ruby v2.5:
# test.rb:
def test
  binding.irb
end
test

# Running the file yields:
From: test.rb @ line 2 :

    1: def test
 => 2:   binding.irb
    3: end
    4: test

irb(main):001:0>

9. Hash#slice added

(Feature #8499).

The ActiveSupport library, which comes bundled with the popular Ruby on Rails framework (but can also be used in isolation) provides many – often controversial – extensions to Ruby’s core classes.

Over the past few years, however, Ruby has gradually been cherry-picking the “best” features and merging them into the core language. Hash#slice is one such method; continuing the trend.

# Ruby v2.5
{a: 1, b: 2, c: 3}.slice(:a, :b)
#=> {:a=>1, :b=>2}

10. SecureRandom.alphanumeric added

(Feature #10849).

To generate a “random string”. Here are a few of them:

require 'securerandom'

SecureRandom.base64 # e.g. "/qWJPsvoxnSe17HrTlzQ7Q=="
SecureRandom.urlsafe_base64 # e.g. "IINbXW4YKjfoncJMpP-CkQ"
SecureRandom.random_bytes # e.g. "\t\x85\xB9\x9C\xD1\f\xD3\xE6t\xB4S^\v-\xFFo"
SecureRandom.random_number # e.g. 0.8993676724126768

11. Net::HTTP::STATUS_CODES

(Feature #12935).

Ruby v2.5 has now defined a hash of all HTTP status codes!

Previously, this was only recorded in documentation, and it was left up to web frameworks such as Rails to define their own “human-friendly” mappings.

Additionally, definitions of the following status codes have been added to ruby:

# Ruby v2.5
require 'net/http/status_codes'
Net::HTTP::STATUS_CODES
{
  # ...
  208 => 'Already Reported',
  308 => 'Permanent Redirect',
  421 => 'Misdirected Request',
  506 => 'Variant Also Negotiates',
  508 => 'Loop Detected',
  510 => 'Not Extended',
  # ...
}

12. String#delete_prefix/delete_suffix

String#delete_prefix/delete_suffix can remove prefix and suffix from a string:

'invisible'.delete_prefix('in') #=> "visible"
'pink'.delete_prefix('in') #=> "pink"
 
'worked'.delete_suffix('ed') #=> "work"
'medical'.delete_suffix('ed') #=> "medical"

Feature #12694: Want a String method to remove heading substr

Feature #13665: String#delete_suffix

13. Array#prepend/append as aliases of unshift/push

Array#prepend/append are added as aliases of unshift/push methods:

array = [3, 4]
array.prepend(1, 2) #=> [1, 2, 3, 4]
array               #=> [1, 2, 3, 4]
 
array = [1, 2]
array.append(3, 4)  #=> [1, 2, 3, 4]
array               #=> [1, 2, 3, 4]

Feature #12746: class Array: alias .prepend to .unshift ?

14. Hash#transform_keys/transform_keys!

Hash#transform_keys can change keys according to the return value of a block:
transform_keys! is a destructive version:

hash = { a: 1, b: 2 }
hash.transform_keys { |k| k.to_s }
#=> { 'a' => 1, 'b' => 2 }

hash.transform_keys! { |k| k.to_s }
#=> { 'a' => 1, 'b' => 2 }
 
hash
#=> { 'a' => 1, 'b' => 2 }

Feature #13583: Adding Hash#transform_keys method

15. Dir.children/each_child

If you want to remove “.” and “..” from the returned values, you can Dir.children instead:

Dir.children('./test/dir_a')
#=> ['code_a.rb', 'text_a.txt']

Dir.each_child returns not an array but an Enumerator object:

Dir.each_child('./test/dir_a')
#=> #<Enumerator: Dir:each_child(\"./test/dir_a\")>"
 
Dir.each_child('./test/dir_a').to_a
#=> ['code_a.rb', 'text_a.txt']

Feature #11302: Dir.entries and Dir.foreach without [“.”, “..”]

16. ERB#result_with_hash

In Ruby 2.5, you can rewrite with ERB#result_with_hash like this:

require 'erb'
 
template = 'Result: <%= a * b %>'
ERB.new(template).result_with_hash(a: 2, b: 3) #=> "Result: 6"

Feature #8631: Add a new method to ERB to allow assigning the local variables from a hash

References

10 new features in Ruby 2.5
https://blog.jetbrains.com/ruby/2017/10/10-new-features-in-ruby-2-5/

10 More New Features in Ruby v2.5 – Tom Lord – Senior Engineer at Team Satchel, London
https://tom-lord.github.io/10-More-New-Features-In-Ruby-2.5/

ruby/NEWS at v2_5_0_preview1 · ruby/ruby
https://github.com/ruby/ruby/blob/v2_5_0_preview1/NEWS

Ruby 2.5 | BigBinary Blog
http://blog.bigbinary.com/categories/Ruby-2-5

打赏

Leave a Reply

Your email address will not be published. Required fields are marked *