10 нових можливостей Ruby 2.5

4 хв. читання
07 листопада 2017

10 жовтня до релізу дійшов Ruby 2.5.0-preview1. Він включає багато нових можливостей і може похизуватися чималою роботою над оптимізацією. У статті зібрано 10 нових фіч, які допоможуть вам зрозуміти деякі з нових можливостей найближчого релізу - Ruby 2.5.

1. rescue/else/ensure тепер доступні усередині do/end блоків, і не потребують begin/end

Тепер можна використовувати класи rescue, else, ensure без ключових слів begin та end:

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

Але якщо ви використовуєте {}, то ви отримаєте помилку:

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

2. Прибрано пошук констант верхнього рівня

У Ruby 2.4 наступний код повертає помилку:

class Staff; end
class ItemsController; end
 
Staff::ItemsController
#=> warning: toplevel constant ItemsController referenced by Staff::ItemsController
#=> ItemsController

Це відбувається через те, що константи верхнього рівня визначені як клас Object, і Ruby намагається знайти суперклас Staff і врешті-решт знаходить ItemsController під класом Object, який є суперкласом Staff.

Проте Ruby 2.5 не буде шукати суперклас. Тож попередній код видає помилку:

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

3. Bundler тепер включено за замовчуванням

Тепер Bundler є стандартною бібліотекою. Тож ви можете використовувати його без gem install bundler.

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

4. Відстеження Print і повідомлень про помилку у зворотньому порядку(експериментально)

У Ruby 2.5 відстеження помилок виводиться у зворотньому порядку. Приклад з Ruby 2.4:

$ ruby ./test/error_example.rb
./test/error_example.rb:7:in `/': divided by 0 (ZeroDivisionError)
    from ./test/error_example.rb:7:in `method_2'
    from ./test/error_example.rb:2:in `method_1'
    from ./test/error_example.rb:10: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)

Як вже було сказано вище, це експериментальна фіча і вона працює лише коли STDERR незмінний і tty.

5. Kernel#yield_self

З новою версією вводиться Kernel#yield_self. Цей метод приймає блоковий аргумент і повертає блокове значення таким чином:

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

6. String#delete_prefix/delete_suffix

String#delete_prefix/delete_suffix прибирає префікс і суфікс зі строки:

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

7. Array#prepend/append як аліаси unshift/push

Array#prepend/Array#append додано як псевдонім методів unshift, push:

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]

8. Hash#transform_keys/transform_keys!

Hash#transform_keys може змінювати ключі відповідно до значення блоку, що повертається:

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

transform_keys! – деструктивна версія:

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

9. Dir.children/each_child

Можливо ви маєте метод Dir.entries:

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

Якщо ви хочете прибрати . та .. зі значень, що повертаються, ви можете використати Dir.children:

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

Dir.each_child повертає замість масиву об'єкт-енумератор:

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']

10. ERB#result_with_hash

Наступний код показує як призначити локальні змінні до шаблону ERB у RUBY2.4.

require 'erb'
require 'ostruct'
 
namespace = OpenStruct.new(a: 2, b: 3)
template = 'Result: <%= a * b %>'
ERB.new(template).result(namespace.instance_eval { binding }) #=> "Result: 6"

Проте у версії 2.5 ви можете переписати ERB#result_with_hash таким чином:

require 'erb'
 
template = 'Result: <%= a * b %>'
ERB.new(template).result_with_hash(a: 2, b: 3) #=> "Result: 6"
Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.6K
Приєднався: 8 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація