Added `Hash#transform_keys` method
transform_values
method, 2.5 completes it by adding transform_keys
thus make it a perfect pair.
Hash#transform_keys can change keys according to the return value of a block:
hash = { a: 1, b: 2 } => {:a=>1, :b=>2} hash.transform_keys { |k| k.to_s } => {"a"=>1, "b"=>2} hash => {:a=>1, :b=>2}
transform_keys!
is a destructive version:
hash = { a: 1, b: 2 } => {:a=>1, :b=>2} hash.transform_keys! { |k| k.to_s } => {"a"=>1, "b"=>2} hash => {"a"=>1, "b"=>2}We know how many times we had to manipulate the keys of a hash.
transform_keys
is gonna be a game changer and going to be very compelling to be used in your legacy app. The destructive version is a just silver lining to this.
-
Array#prepend and Array#append
>> a = ["hello"] => ["hello"] >> a.append "world" => ["hello", "world"] >> a.prepend "Hi" => ["Hi", "hello", "world"]
-
Added yield_self method
yield_self
method returns the output of the block but tap
method returns the receiver itself.
"Hello".yield_self { |obj| obj + " World"} => "Hello World" "Hello".tap { |obj| obj + " World" } => "Hello"
-
rescue/else/ensure are allowed inside do/end blocks without begin/end
[1].each do |n| n / 0 rescue # rescue else # else ensure # ensure end
-
String#delete_prefix/delete_suffix
'HelloWorld'.delete_prefix('Hello') => "World" 'HelloWorld'.delete_suffix('World') => "Hello"
-
Ruby 2.5 has removed top-level constant lookup
class Book; end class Seller; end Book::SellerThis code works with a warning. The top-level constants are defined under Object class, and Ruby tries to look up the superclass of Book class, and eventually finds Seller under the Object class which is a superclass of Book class. But in Ruby 2.5, Ruby won’t look up superclass. So the previous code fails with an error.
Book::Seller #=> NameError: uninitialized constant Book::Seller # Did you mean? SellerRuby 2.5 throws an error if it is unable to find constant in the specified scope.
-
New method to ERB to allow assigning the local variables from a hash
require 'erb' require 'ostruct' namespace = OpenStruct.new(a: 10, b: 3) template = 'Result: <%= a * b %>' ERB.new(template).result(namespace.instance_eval { binding }) #=> "Result: 30"ERB could allow a hash instead of a binding for processing the template in Ruby 2.5 such that we could avoid hacks as above. To allow assigning the local variables from a hash we can use
result_with_hash
method.
require 'erb' result = 'Result: <%= a * b %>' ERB.new(result).result_with_hash(a: 10, b: 3) #=> "Result: 30"
-
Dir.children and Dir.each_child
Dir.entries("/home") => ["..", "user", "."]Another method Dir.foreach iterates and yields each value from the output of ls -a command to the block.
Dir.foreach("/home") { |child| puts child } .. user .The output includes the directives for the current directory and parent directory which are “.” and “..”. When we want to have access only to the children files and directories, we do not need the [“.”, “..”] subarray. To overcome such issues, Ruby 2.5 introduced Dir.children. It returns the output of ls -a command without the directives for current and parent directories.
Dir.children("/home") => ["user"]We can use Dir.each_child method to avoid yielding current and parent directory directives while iterating.
Dir.each_child("/home") { |child| puts child } user
-
Imported features from ActiveSupport library
Hash#slice
, Hash#slice!
, Hash#except
, Hash#except!
are such methods continuing the trend, imported from ActiveSupport.
The ActiveSupport library comes bundled with the popular Ruby on Rails framework, but can also be used in isolation. It provides many extensions to Ruby’s core classes.
{a: 1, b: 2, c: 3}.slice(:a, :b) #=> {:a=>1, :b=>2}One of the notable feature in 2.5 release was bundler packed with ruby core, but it is posponed due to some issues, See the commit