What's new in Ruby 2.5

  • Added `Hash#transform_keys` method

  • Ruby 2.4 added the 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

    Ruby 2.5 brings home two new aliases which are so much better than the two of the most used operations in the language. `Array#prepend` and `Array#append` are more programmer friendly than the conventional `Array#unshift` and `Array#push`. Ruby IS THE language which focuses on the programmers’ happiness primarily after all.
    >> a = ["hello"]
    => ["hello"]
    >> a.append "world"
    => ["hello", "world"]
    >> a.prepend "Hi"
    => ["Hi", "hello", "world"]
    • Added yield_self method

    This method yields the receiver to the given block and returns the output of the last statement in the block which is somewhat similar to the tap method.The only difference is the value that is returned.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

    We could omit the begin/end and not need the extra wrapper for rescue/else/ensure clauses in Ruby 2.5
    [1].each do |n|
      n / 0
    rescue
      # rescue
    else
      # else
    ensure
      # ensure
    end
    • String#delete_prefix/delete_suffix

    In Ruby 2.4 we used chomp method to remove the suffix ‘world’ from ‘HelloWorld’ and to remove prefix there is no corresponding method for chomp. The solution was to resort to a sub which is using the regular expression for such a simple task. Ruby 2.5 added new methods to take care of such tasks. Now in order to delete prefix, we can use delete_prefix and to delete suffix we could use chomp. But the method names don’t seem good. So for symmetry delete_suffix was added.
    'HelloWorld'.delete_prefix('Hello')
    => "World" 
    'HelloWorld'.delete_suffix('World')
    => "Hello"
    • Ruby 2.5 has removed top-level constant lookup

    Consider the following code in Ruby 2.4.
    class Book;
    end
    class Seller;
    end
     
    Book::Seller
    This 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?  Seller
    Ruby 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

    In Ruby 2.4, we had to do hacks like following to assign local variables to ERB template.
    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

    ls -a command will list all files including hidden files (files with names beginning with a dot). Dir.entries  method present in Ruby 2.4 returns this output in an array.
    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

    Over the past few years, Ruby has been merging the best features from the ActiveSupport library, into the core language. In Ruby 2.5 version, Hash#sliceHash#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

    Further changes

    NEWS for Ruby 2.5.0  news page can be referred to find other news and changes on Ruby 2.5

    References

     ]]>